/*程式介紹:此為使用者與電腦之雙方井字遊戲,使用者透過輸入1-9的數字來換算成實際的
陣列座標,而電腦則是使用亂數法則來取1-9的數字並且一樣換算成陣列座標

ps:此程式並沒有加入AI人工智慧的部分!!!
*/

#include<iostream>
#include<iomanip>
#include<cstdlib>
#include<ctime>
using namespace std;

bool user_play(char map[3][3],bool user_sign);//使用者遊戲

bool pc_play(char map[3][3],bool pc_sign);//電腦遊戲

void draw_prompt_map(char map[3][3]);//畫出提示圖,告訴使用者遊戲玩法         

bool judge_repeat(char map[3][3],int location,bool sign);//判斷是否有重複畫記號

void draw_map(char map[3][3]);//畫出遊戲中的井字圖

bool judge_line(char map[3][3],bool sign);//判斷各種連線狀況

void clear_map(char map[3][3]);//將陣列中的字元全部指定成空白字元,以便重新遊戲

bool full_map(char map[3][3]);//當表格全滿的時候,傳回true

int main()
{
    bool user_win = false;
    bool pc_win = false;
    bool user_sign,pc_sign;//判斷使用者的符號與電腦的符號
    char map[3][3];
    char ch;//輔助字元
    int location;
     
        cout<<"*******************歡迎光臨井字遊戲******************\n"<<endl;
     do{
        cout<<"輸入1,可以使用o來畫記號。"<<endl;
        cout<<"輸入2,可以使用x來畫記號。"<<endl;
        cin>>ch;
        if(ch=='1')
        {
            user_sign = true;
            pc_sign = false;
        }   
        else if(ch=='2')
        {
            user_sign = false;
            pc_sign = true;
        }
     }while(ch!='1' && ch!='2');//當使用輸入1或2以外的數字時,會要求使用重新輸入
           
    draw_prompt_map(map);
   do{
      
       clear_map(map);//將陣列中的字元全部指定成空白字元
      
          do{
               user_win = user_play(map,user_sign);
                if(full_map(map))
               {
                   break;//表格全滿時,跳出迴圈   
               }
               pc_win = pc_play(map,pc_sign);
               if(full_map(map))
               {
                   break;//表格全滿時,跳出迴圈
               }                                 
           
           } while(!user_win && !pc_win);//當雙方都還沒有贏的時候,繼續遊戲
        if(user_win)
                cout<<"恭喜你!!你贏了囉^_^!!!"<<endl;
        else if(pc_win)
                cout<<"你輸囉~~~~>.<~~~"<<endl;
        else
                cout<<"平手喔@_@..."<<endl;
               
        cout<<"要繼續玩嗎??(y)繼續 or (n)結束)"<<endl;
        cin>>ch;
        system("cls");//清除螢幕
    }while(ch=='y' || ch=='Y');     
            
    system("pause");      
}   

bool user_play(char map[3][3],bool user_sign)
{
       int location;
       bool user_or_pc = true;//判斷目前正在遊戲的一方,true為使用者
       cout<<"請選擇您要畫記號的位置?"<<endl;
       cin>>location;
       while(judge_repeat(map,location,user_sign))//當判斷位置重複時候,重新輸入位置
       {
           cout<<"請輸入您要畫記號的位置?"<<endl;
           cin>>location;   
       }
       draw_map(map);

       if(judge_line(map,user_sign))//當判斷連線成功的時候,傳回true
       {
              return true;
       }  
       return false;
}
bool pc_play(char map[3][3],bool pc_sign)
{
    int location ;
    bool user_or_pc = false;//判斷目前正在遊戲的一方,false為電腦
    srand(time(0));
    location = rand()%9+1;
   
    //當判斷重複的時候,再一次使用亂數來取位置
    while(judge_repeat(map,location,pc_sign))
    {
        location = rand()%9+1;
    }     
         draw_map(map);      
    if(judge_line(map,pc_sign))//當電腦連線成功的時候,傳回true
    {
        return true;
    }  
       return false;
   }   
   
//畫出提示圖,告訴使用者遊戲玩法   
void draw_prompt_map(char map[3][3])
{
    int num = 1;
    cout<<"\n格子中的數字代表輸入代號!"<<endl;
    for(int row=0; row<3; row++)//利用迴圈來畫出井字表格
    {
        for(int column=0; column<3; column++,num++)
        {
            //int的整數值加上48之後,等於char的同等整數(由ascii表得知)
            map[row][column] = num+48;
            cout<<"  "<<map[row][column]<< setw(4);
            if(column<=1)cout<<"|";
            map[row][column] = ' ';
        }
        cout<<endl;
        if(row<=1)cout<<"--------------------";
        cout<<endl;
    }
}
//判斷是否有重複畫記號
bool judge_repeat(char map[3][3],int location,bool sign)
{
    int row,column;
    //由於陣列索引值是從0開始,但是位置的數字是從1開始,所以要減1才能符合陣列索引規則
    location--;
   
        row = location/3 ;//將輸入的數字換成表格 列 座標
        column = location % 3;//將輸入的數字換成表格 行 座標   
        if(map[row][column]== ' ')
        {
            if(sign==true)//判斷傳入的sign是true就畫上O
            {
                map[row][column] ='O';//畫上記號
            }
            else //反之,就畫上X
            {
                map[row][column] ='X';//畫上記號   
            }                 
            return false;//代表沒有重複
        }
        else
        {
            return  true;
        }   
                    
}  
//畫出遊戲中的井字圖
void draw_map(char map[3][3])      
{
    int row,column;
   
    for(row=0; row<3; row++)//利用迴圈來設置表格
    {
        for(column=0; column<3; column++)
        {
            cout<<setw(3)<<map[row][column]<< setw(4);
            if(column<=1)cout<<"|";   
        }
        cout<<endl;
        if(row<=1)cout<<"--------------------";
        cout<<endl;
    }
}   

  //判斷各種連線狀況  
bool judge_line(char map[3][3],bool sign)
{
    int counter=0,row,column;
    char process_sign;
    if(sign==true)
    {
        process_sign ='O';//決定要判斷是否連線的符號
    }
    else
    {
        process_sign ='X';//決定要判斷是否連線的符號
    }      
        
    for(row=0 ;row<3; row++)//判斷每行是否有連線
    {               
         for(column=0; column<3 ; column++)
         {
            if(map[row][column]==process_sign)
                counter++;
            if(counter==3)/*連線成功*/
                return true;
         }
         counter = 0;
    }   
      for(column=0; column<3 ; column++) //判斷每列是否有連線
      {
         for(row=0 ;row<3; row++)
         {
           if(map[row][column]==process_sign)
              counter++;
           if(counter==3)/*連線成功*/
                return true;
         }
         counter = 0;
      }
      
     counter=0;
     for(row=0 ;row<3; row++)//判斷右下方向對角線是否有連線
    {
        if(map[row][row]==process_sign)
        {
            counter++;
         if(counter==3)/*連線成功*/
           return true;
        }  
    }   
    //判斷右上方向對角線是否有連線
    if(map[0][2]==map[1][1] && map[1][1]==map[2][0] && map[2][0]==process_sign)
    {
        return true;/*連線成功*/
    }        
     
    return false;
}   

//將陣列中的字元全部指定成空白字元
void clear_map(char map[3][3])
{
    for(int row=0; row<3; row++)
    {
        for(int column=0; column<3; column++)
        {
            map[row][column]=' ';
        }
    }
}            
//計算表格是否全滿
bool full_map(char map[3][3])
{
    int no_white_space=0;
    for(int row=0; row<3; row++)
    {
        for(int column=0; column<3; column++)
        {
            if(map[row][column]!=' ')
            {
                no_white_space++;
            }
        }
    }
    //當表格沒有任何的white space 時,代表全滿,並且傳回true
    if(no_white_space==9)
    {
        return true;
    }
    else
        return false;   
}                 

創作者介紹
創作者 jethro0119 的頭像
jethro0119

滷蛋與貢丸

jethro0119 發表在 痞客邦 留言(0) 人氣()