設計題目:井字棋游戲設計與實作 游戲簡介:一種在井字格上進行的連珠游戲,由分別代表O和X的兩個游戲者輪流在格子里落子,任意三子形成一條直線,則為獲勝,今天,小明發明了新玩法:①棋盤3x3大小,獲勝條件不變;②當一方落下第4子仍未獲勝時,則其落下的第1子會被拿掉,依次類推,
類似文章很多,但是可以拿走棋子的較少,故本文著重講解拿走棋子部分
頭檔案
#include <stdio.h>
#include <windows.h>
#include<stdlib.h>//用于產生亂數
//全域變數
int QP[3][3];//棋盤,1為√,2為×,0為空
int qp1[8] = { 0 }, qp2[8] = { 0 };//用于存數以便于每六步消子
int player=1;//1為√ 玩家,2為× 玩家2或電腦
int cnt1=0,cnt2=0;
int judge_win();//判斷輸贏
void gotoxy(int x, int y);//跳轉游標
void print_menu();//選單
void print_box();//棋盤
void move_player1();//√下棋
void move_player2(int oder);//×下棋
int game(int oder);//游戲本體
void turn();//玩家狀態
void updatebox();//更新棋盤
void xiaozi();//消去棋子
主函式
int main()
{
int oder;
system("mode con cols=90 lines=35");
begin:
print_menu();
scanf("%d", &oder);
for (int a = 0; a < 3; a++)
for (int b = 0; b < 3; b++)
QP[a][b] = 0;//初始化a,b
switch (oder)
{
case 0:
return 0;
break;
case 1:
game(oder);
break;
case 2:
game(oder);
break;
default:
printf("輸入錯誤回傳選單\n");
goto begin;
}
return 0;
}
拿走棋子:
原理:定義兩個陣列,用于存放已下棋子的坐標(qb1和qp2),然后用cnt來計數,當到了第四步(由于使用一維陣列存數,故此時cnt=8)時,則將第一次所下棋子坐標賦值為0(代表此處沒有棋子),并更新棋盤,后續步驟則用%來更新存放棋子坐標的陣列(指qb1和qp2)
void xiaozi()
{
if (cnt1 >= 8)
{
QP[qp1[(cnt1) %8]][qp1[((cnt1)%8+1)]] = 0;
updatebox();
}
if (cnt2 >= 8)
{
QP[qp2[(cnt2) % 8]][qp2[((cnt2) % 8 + 1)]] = 0;
updatebox();
}
}
開始選單
void print_menu()
{
printf("請輸入:\n1 玩家對戰\n2 普通人機\n0 退出游戲\n");
}
列印棋盤
void print_box()
{
gotoxy(26, 5);
printf(" ┃ ┃ ");
gotoxy(26, 6);
printf(" ┃ ┃ ");
gotoxy(26, 7);
printf(" ┃ ┃ ");
gotoxy(26, 8);
printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
gotoxy(26, 9);
printf(" ┃ ┃ ");
gotoxy(26, 10);
printf(" ┃ ┃ ");
gotoxy(26, 11);
printf(" ┃ ┃ ");
gotoxy(26, 12);
printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
gotoxy(26, 13);
printf(" ┃ ┃ ");
gotoxy(26, 14);
printf(" ┃ ┃ ");
gotoxy(26, 15);
printf(" ┃ ┃ \n");
}
玩家1移動
void move_player1()
{
do
{
gotoxy(60, 15);
printf(" ");
gotoxy(60, 6);
printf("請輸入x軸坐標: ");
gotoxy(60, 7);
printf("請輸入y軸坐標: ");
gotoxy(60, 6);
int x, y;
printf("請輸入x軸坐標:");
scanf("%d", &x);
gotoxy(60, 7);
printf("請輸入y軸坐標:");
scanf("%d", &y);
if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
{
gotoxy(60, 15);
printf("x,y的值在1到3之間,請重輸");
continue;
}
if (QP[x - 1][y - 1] != 0)
{
gotoxy(60,15);
printf("此處有棋子,請重輸");
continue;
}
else
{
QP[x - 1][y - 1] = 1;
qp1[cnt1 %8] = x - 1;
qp1[(cnt1+1)%8] = y - 1;
break;
}
} while (1);
updatebox();
player =
玩家二
void move_player2(int oder)
{
if (oder == 1) //玩家
{
do
{
gotoxy(60, 15);
printf(" ");
gotoxy(60, 6);
printf("請輸入x軸坐標: ");
gotoxy(60, 7);
printf("請輸入y軸坐標: ");
gotoxy(60, 6);
int x, y;
printf("請輸入x軸坐標:");
scanf("%d", &x);
gotoxy(60, 7);
printf("請輸入y軸坐標:");
scanf("%d", &y);
if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
{
gotoxy(60, 15);
printf("x,y的值在1到3之間,請重輸");
continue;
}
if (QP[x - 1][y - 1] != 0)
{
gotoxy(60, 15);
printf("此處有棋子,請重輸");
continue;
}
else
{
QP[x - 1][y - 1] = 2;
qp2[cnt2 % 8] = x - 1;
qp2[(cnt2 + 1) % 8] = y - 1;
break;
}
} while (1);
}else if(oder==2)
{
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (QP[x][y] == 0)
{
QP[x][y] = 2;
break;
}
}
}
updatebox();
player = 1;
}
游戲體
int game(int oder)
{
print_box();
do
{
turn();//顯示到誰
move_player1();
judge_win();
if (judge_win() != 0)
break;
cnt1 += 2;
xiaozi();
turn();
move_player2(oder);
judge_win();
if (judge_win() != 0)
break;
cnt2 += 2;
xiaozi();
} while (1);
if (judge_win ()==1 )
MessageBox(NULL, TEXT("√贏了"), TEXT("游戲結束"), 0);
else if(judge_win ()==2)
MessageBox(NULL, TEXT("×贏了"), TEXT("游戲結束"), 0);
return 0;
}
列印游戲動態
void turn()
{
gotoxy(60, 5);
printf(" ");
gotoxy(60, 5);
if(player==1)
printf("√");
else if(player == 2)
printf("×");
gotoxy(63, 5);
printf("走");
}
更新棋盤
void updatebox()
{
int a, b;//用于計算列印棋子的位置
for(a=0;a<3;a++)
for (b = 0; b < 3; b++)
{
if (QP[a][b] == 1)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf("√");
}else if (QP[a][b] == 2)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf("×");
}
else if (QP[a][b] == 0)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf(" ");
}
}
}
判斷輸贏
int judge_win()
{
for (int r = 0; r < 3; r++)
{
//√贏回傳1,×贏回傳2
//三橫三豎的判斷
if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 1 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 1)
return 1;
if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 2 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 2)
return 2;
}
if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==1 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] ==1)
return 1;
if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==2 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] == 2)
return 2;
return 0;
}
移動游標
void gotoxy(int x, int y)
{
COORD pos = { x,y };
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);//設定游標位置,并移動到相應位置
}//
總代碼
#include <stdio.h>
#include <windows.h>
#include<stdlib.h>//用于產生亂數
//全域變數
int QP[3][3];//棋盤,1為√,2為×,0為空
int qp1[8] = { 0 }, qp2[8] = { 0 };//用于存數以便于每六步消子
int player=1;//1為√ 玩家,2為× 玩家2或電腦
int cnt1=0,cnt2=0;
int judge_win();//判斷輸贏
void gotoxy(int x, int y);//跳轉游標
void print_menu();//選單
void print_box();//棋盤
void move_player1();//√下棋
void move_player2(int oder);//×下棋
int game(int oder);//游戲本體
void turn();//玩家狀態
void updatebox();//更新棋盤
void xiaozi();//消去棋子
int main()
{
int oder;
system("mode con cols=90 lines=35");
begin:
print_menu();
scanf("%d", &oder);
for (int a = 0; a < 3; a++)
for (int b = 0; b < 3; b++)
QP[a][b] = 0;//初始化a,b
switch (oder)
{
case 0:
return 0;
break;
case 1:
game(oder);
break;
case 2:
game(oder);
break;
default:
printf("輸入錯誤回傳選單\n");
goto begin;
}
return 0;
}
void print_menu()
{
printf("請輸入:\n1 玩家對戰\n2 普通人機\n0 退出游戲\n");
}
void print_box()
{
gotoxy(26, 5);
printf(" ┃ ┃ ");
gotoxy(26, 6);
printf(" ┃ ┃ ");
gotoxy(26, 7);
printf(" ┃ ┃ ");
gotoxy(26, 8);
printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
gotoxy(26, 9);
printf(" ┃ ┃ ");
gotoxy(26, 10);
printf(" ┃ ┃ ");
gotoxy(26, 11);
printf(" ┃ ┃ ");
gotoxy(26, 12);
printf("━━━━━━━━╂━━━━━━━━╂━━━━━━━━");
gotoxy(26, 13);
printf(" ┃ ┃ ");
gotoxy(26, 14);
printf(" ┃ ┃ ");
gotoxy(26, 15);
printf(" ┃ ┃ \n");
}
void move_player1()
{
do
{
gotoxy(60, 15);
printf(" ");
gotoxy(60, 6);
printf("請輸入x軸坐標: ");
gotoxy(60, 7);
printf("請輸入y軸坐標: ");
gotoxy(60, 6);
int x, y;
printf("請輸入x軸坐標:");
scanf("%d", &x);
gotoxy(60, 7);
printf("請輸入y軸坐標:");
scanf("%d", &y);
if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
{
gotoxy(60, 15);
printf("x,y的值在1到3之間,請重輸");
continue;
}
if (QP[x - 1][y - 1] != 0)
{
gotoxy(60,15);
printf("此處有棋子,請重輸");
continue;
}
else
{
QP[x - 1][y - 1] = 1;
qp1[cnt1 %8] = x - 1;
qp1[(cnt1+1)%8] = y - 1;
break;
}
} while (1);
updatebox();
player = 2;
}
void move_player2(int oder)
{
if (oder == 1) //玩家
{
do
{
gotoxy(60, 15);
printf(" ");
gotoxy(60, 6);
printf("請輸入x軸坐標: ");
gotoxy(60, 7);
printf("請輸入y軸坐標: ");
gotoxy(60, 6);
int x, y;
printf("請輸入x軸坐標:");
scanf("%d", &x);
gotoxy(60, 7);
printf("請輸入y軸坐標:");
scanf("%d", &y);
if ((x > 3) || (x < 0) || (y < 0) || (y > 3))
{
gotoxy(60, 15);
printf("x,y的值在1到3之間,請重輸");
continue;
}
if (QP[x - 1][y - 1] != 0)
{
gotoxy(60, 15);
printf("此處有棋子,請重輸");
continue;
}
else
{
QP[x - 1][y - 1] = 2;
qp2[cnt2 % 8] = x - 1;
qp2[(cnt2 + 1) % 8] = y - 1;
break;
}
} while (1);
}else if(oder==2)
{
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (QP[x][y] == 0)
{
QP[x][y] = 2;
break;
}
}
}
updatebox();
player = 1;
}
int game(int oder)
{
print_box();
do
{
turn();//顯示到誰
move_player1();
judge_win();
if (judge_win() != 0)
break;
cnt1 += 2;
xiaozi();
turn();
move_player2(oder);
judge_win();
if (judge_win() != 0)
break;
cnt2 += 2;
xiaozi();
} while (1);
if (judge_win ()==1 )
MessageBox(NULL, TEXT("√贏了"), TEXT("游戲結束"), 0);
else if(judge_win ()==2)
MessageBox(NULL, TEXT("×贏了"), TEXT("游戲結束"), 0);
return 0;
}
void turn()
{
gotoxy(60, 5);
printf(" ");
gotoxy(60, 5);
if(player==1)
printf("√");
else if(player == 2)
printf("×");
gotoxy(63, 5);
printf("走");
}
void updatebox()
{
int a, b;//用于計算列印棋子的位置
for(a=0;a<3;a++)
for (b = 0; b < 3; b++)
{
if (QP[a][b] == 1)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf("√");
}else if (QP[a][b] == 2)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf("×");
}
else if (QP[a][b] == 0)
{
gotoxy(30 + a * 8, 6 + b * 4);
printf(" ");
}
}
}
void xiaozi()
{
if (cnt1 >= 8)
{
QP[qp1[(cnt1) %8]][qp1[((cnt1)%8+1)]] = 0;
updatebox();
}
if (cnt2 >= 8)
{
QP[qp2[(cnt2) % 8]][qp2[((cnt2) % 8 + 1)]] = 0;
updatebox();
}
}
int judge_win()
{
for (int r = 0; r < 3; r++)
{
//√贏回傳1,×贏回傳2
//三橫三豎的判斷
if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 1 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 1)
return 1;
if (QP[r][0] == QP[r][1] && QP[r][2] == QP[r][1] && QP[r][1] == 2 || QP[0][r] == QP[1][r] && QP[2][r] == QP[1][r] && QP[1][r] == 2)
return 2;
}
if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==1 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] ==1)
return 1;
if (QP[0][0] == QP[1][1] && QP[1][1] == QP[2][2] && QP[1][1] ==2 || QP[0][2] == QP[1][1] && QP[1][1] == QP[2][0] && QP[1][1] == 2)
return 2;
return 0;
}
void gotoxy(int x, int y)
{
COORD pos = { x,y };
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);//設定游標位置,移動到
}//
本代碼存在列印bug,有兩段文字無法被列印
本文為sztu學生張fm的大一上作業,要交給s小樂老師,為防止作業出現雷同特此宣告,為完成博客任務不被卷死,只能發文來湊數.................
代碼參考: https://b23.tv/9dCyt4B
實作若想要實作人工智能可參考(本代碼無):(27條訊息) 關于井字棋/三子棋的偽人工智能演算法的實作_DanteKing的博客-CSDN博客_井字棋ai演算法
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/388014.html
標籤:其他
