/*物件導向版本的井字遊戲
程式介紹:此為使用者與電腦之雙方井字遊戲,使用者透過輸入1-9的數字來換算成實際的
陣列座標,而電腦則是使用亂數法則來取1-9的數字並且一樣換算成陣列座標
ps:此程式並沒有加入AI人工智慧的部分!!!
*/
#include
#include
#include
using namespace std;

class tictactoe
{
private:
int table[3][3];//此為遊戲的表格

public:
tictactoe();//建構子
void draw_prompt_table();//畫出提示圖,告訴使用者遊戲玩法
bool user_playing(int input_sign);//使用者遊戲
bool pc_playing(int input_sign);//電腦遊戲
bool judge_repeat(int location,int sign);//判斷是否有重複畫記號
bool judge_line(int process_sign);//判斷各種連線狀況
void draw_table();//畫出遊戲中的井字圖
bool full_table();//當表格全滿的時候,傳回true
void clear_table();//將陣列中數值重新規零,以便重新遊戲
};

//建構子,作為初始化表格為零
tictactoe::tictactoe()
{
int row,column;
for(row=0; row<3; row++)
{
for(column=0; column<3; column++)
{
table[row][column] = 0;
}
}
}
//畫出提示圖,告訴使用者如何遊戲
void tictactoe::draw_prompt_table()
{
int num = 1;
cout<<"\n格子中的數字代表輸入代號!"< for(int row=0; row<3; row++)//利用迴圈來畫出井字表格
{
for(int column=0; column<3; column++,num++)
{
table[row][column] = num;
cout<<" "< if(column<=1)cout<<"|";
table[row][column] = 0;
}
cout< if(row<=1)cout<<"--------------------";
cout< }
}

bool tictactoe::user_playing(int input_sign)
{
int location;

cout<<"請輸入位置"< cin>>location;
while(judge_repeat(--location,input_sign))//將位置減一化成與陣列相對的索引值
{
cout<<"位置重複,請輸入位置"< cin>>location;
}
draw_table();//畫出目前的遊戲圖
if(judge_line(input_sign))//判斷是否連線
{
return true;
}
else
return false;
}
bool tictactoe::pc_playing(int input_sign)
{
int location;
location = rand()%9+1;

//當判斷重複的時候,再一次使用亂數來取位置
while(judge_repeat(--location,input_sign))
{
location = rand()%9+1;
}
draw_table();
if(judge_line(input_sign))//當電腦連線成功的時候,傳回true
{
return true;
}
return false;
}


bool tictactoe::judge_repeat(int location,int sign)
{
int row,column;
//由於陣列索引值是從0開始,但是位置的數字是從1開始,所以要減1才能符合陣列索引規則

row = location/3 ;//將輸入的數字換成表格 列 座標
column = location % 3;//將輸入的數字換成表格 行 座標
if(table[row][column]==0)
{
table[row][column] =sign;//畫上記號
return false;//代表沒有重複
}
else
{
return true;//有重複
}
}



bool tictactoe::judge_line(int process_sign)
{
int counter=0,row,column;

for(row=0 ;row<3; row++)//判斷每行是否有連線
{
for(column=0; column<3 ; column++)
{
if(table[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(table[row][column]==process_sign)
counter++;
if(counter==3)/*連線成功*/
return true;
}
counter = 0;
}

counter=0;
for(row=0 ;row<3; row++)//判斷右下方向對角線是否有連線
{
if(table[row][row]==process_sign)
{
counter++;
if(counter==3)/*連線成功*/
return true;
}
}
//判斷右上方向對角線是否有連線
if(table[0][2]==table[1][1] && table[1][1]==table[2][0] && table[2][0]==process_sign)
{
return true;/*連線成功*/
}

return false;
}
void tictactoe::draw_table()
{
int row,column;

for(row=0; row<3; row++)//利用迴圈來設置表格
{
for(column=0; column<3; column++)
{
cout< if(column<=1)cout<<"|";
}
cout< if(row<=1)cout<<"--------------------";
cout< }
}

bool tictactoe:: full_table()
{
int no_white_space=0;
for(int row=0; row<3; row++)
{
for(int column=0; column<3; column++)
{
if(table[row][column]!= 0)
{
no_white_space++;
}
}
}
//當表格沒有任何的white space 時,代表全滿,並且傳回true
if(no_white_space==9)
{
return true;
}
else
return false;
}

void tictactoe:: clear_table()
{
for(int row=0; row<3; row++)
{
for(int column=0; column<3; column++)
{
table[row][column]= 0;
}
}
}
//使用者優先的模式
bool user_first_mode(tictactoe& board, bool& user_win,bool& pc_win, int& user_sign, int& pc_sign);

//電腦優先的模式
bool pc_first_mode(tictactoe& board, bool& user_win,bool& pc_win, int& user_sign, int& pc_sign);

int main()
{
tictactoe board;//建立井字遊戲物件

int user_sign,pc_sign;
bool user_win = false;
bool pc_win = false;
bool full_table = false;//判斷表格是否全滿
char choice,go_on;

board.draw_prompt_table();//畫出提示圖

cout<<"你要先玩嗎??(y/n)"< cin>>choice;

if(choice=='y'||choice=='Y')
{
cout<<"請輸入你要的記號,請選擇1或是2"< cin>>user_sign;
while(user_sign!=1 && user_sign!=2)
{
cout<<"無效的輸入請重新選擇1或是2"< cin>>user_sign ;
}
pc_sign = (user_sign==1? 2 : 1);
}
else
{
srand(time(0));
pc_sign = rand()%2+1;
cout<<"電腦已經選擇了使用數字"< user_sign = (pc_sign==1? 2 : 1);
}
do{
board.clear_table();//將陣列中的數值指定為零
do{
if(choice=='y'||choice=='Y')
{
full_table = user_first_mode(board,user_win, pc_win,user_sign,pc_sign);
if(full_table)break;
}
else
{
full_table = pc_first_mode(board,user_win,pc_win,user_sign,pc_sign);
if(full_table)break;
}

} while(!user_win && !pc_win );//當雙方都還沒有贏的時候,繼續遊戲
if(user_win)
cout<<"恭喜你!!你贏了囉^_^!!!"< else if(pc_win)
cout<<"你輸囉~~~~>.<~~~"< else
cout<<"平手喔@_@..."<
cout<<"要繼續玩嗎??(y)繼續 or (n)結束)"< cin>>go_on;
system("cls");//清除螢幕
}while(go_on=='y' || go_on=='Y');

system("pause");
}

bool user_first_mode(tictactoe& board, bool& user_win,bool& pc_win, int& user_sign, int& pc_sign)
{
user_win = board.user_playing(user_sign);//使用者先畫圖
if(board.full_table())
{
return true;//表格全滿時,跳出迴圈
}
pc_win = board.pc_playing(pc_sign);//然後電腦畫圖
if(board.full_table())
{
return true;//表格全滿時,跳出迴圈
}
return false;
}
bool pc_first_mode(tictactoe& board, bool& user_win,bool& pc_win, int& user_sign, int& pc_sign)
{
pc_win = board.pc_playing(pc_sign);//電腦先畫圖
if(board.full_table())
{
return true;//表格全滿時,跳出迴圈
}
user_win = board.user_playing(user_sign);//然後使用者畫圖
if(board.full_table())
{
return true;//表格全滿時,跳出迴圈
}
return false;
}

arrow
arrow
    全站熱搜

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