设计题目:井字棋游戏设计与实现 游戏简介:一种在井字格上进行的连珠游戏,由分别代表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算法