三子棋设计
1. 游戏菜单
打印菜单,0退出游戏,1开始游戏,输入其他的情况就重新输入。
game()为游戏主体实现部分。
void menu()
{printf("*************\n");printf("***0. exit***\n");printf("***1. play***\n");printf("*************\n");printf("请输入:>");
}
int main()
{int input = 0;do{menu();scanf("%d", &input);switch (input){case 0:printf("退出游戏\n");break;case 1:game();break;default:printf("输入错误, 重新输入\n");break;}} while (input);return 0;
}
2. 游戏主体
创建三子棋棋盘a[LEN][LEN],棋盘长度为LEN=3。
1号落子为SIGN1;2号落子为SIGN2。
flag为当前几号落子。
#define LEN 3
#define SIGN1 '*'
#define SIGN2 '#'void game()
{char a[LEN][LEN];Init(a);Print(a);//1号先手int flag = 1;do{int x, y;//判断几号落子,给出提示if (flag == 1)printf("1号落子%c坐标:>", SIGN1);else if (flag == 2)printf("2号落子%c坐标:>", SIGN2);scanf("%d %d", &x, &y);
}
Init()函数初始化,棋盘里全部初始化成空格 ’ '。
Print()打印棋盘。
void Init(char a[LEN][LEN])
{for (int i = 0; i < LEN; i++)for (int j = 0; j < LEN; j++)a[i][j] = ' ';
}
void Print(char a[LEN][LEN])
{printf("\n ");for (int i = 0; i < LEN; i++)printf("%d ", i);printf("\n");for (int i = 0; i < LEN; i++){printf("%d ", i);for (int j = 0; j < LEN; j++){printf("%c ", a[i][j]);}printf("\n");}printf("\n");
}
3.输入坐标落子
Set()设置坐标
a为二维数组棋盘
x,y为坐标
flag为当前几号
如果输入的坐标已落子或超出棋盘范围之外,则落子失败返回0
坐标合法则a[x][y]输入字符,落子成功返回1
int Set(char a[LEN][LEN], int x, int y, int flag)
{if ((a[x][y] == SIGN1 || a[x][y] == SIGN2) ||(x < 0 || x >= LEN) ||(y < 0 || y >= LEN)){printf("坐标有误,重新输入\n");//落子失败return 0;}//若是1号则给SIGN1a[x][y] = (flag == 1) ? SIGN1 : SIGN2;//落子成功return 1;
}
4.判断获胜或平局
未有人获胜且棋盘已满,则平局
int Ass(char a[LEN][LEN], int flag)
{//先判断落子后有无获胜者char c = (flag == 1) ? SIGN1: SIGN2;if ((a[0][0] == c && a[0][1] == c && a[0][2] == c) ||(a[1][0] == c && a[1][1] == c && a[1][2] == c) ||(a[2][0] == c && a[2][1] == c && a[2][2] == c) ||(a[0][0] == c && a[1][0] == c && a[2][0] == c) ||(a[0][1] == c && a[1][1] == c && a[2][1] == c) ||(a[0][2] == c && a[1][2] == c && a[2][2] == c) ||(a[0][0] == c && a[1][1] == c && a[2][2] == c) ||(a[0][2] == c && a[1][1] == c && a[2][0] == c)){printf("%d号获胜\n\n", flag);//有人获胜则返回0,game()终止return 0;}//若无人获胜则判断棋盘是否已满,满了则返回0,game()终止int f = 0;for (int i = 0; i < LEN; i++){for (int j = 0; j < LEN; j++){if (a[i][j] != SIGN1 && a[i][j] != SIGN2){//若发现还有为落子的地方则提前breakf = 1;break;}}//提前breakif (f)break;}//若f棋盘已满则返回0if (f == 0){printf("平局\n\n");return 0;}//没人获胜,棋盘未满,游戏继续,返回1return 1;
}
void game()
{char a[LEN][LEN];Init(a);Print(a);//1号先手int flag = 1;do{int x, y;//判断几号落子,给出提示if (flag == 1)printf("1号落子%c坐标:>", SIGN1);else if (flag == 2)printf("2号落子%c坐标:>", SIGN2);scanf("%d %d", &x, &y);int r = Set(a, x, y, flag);//落子成功,则换人if (r)flag = (flag == 1) ? 2 : 1;Print(a);} while (Ass(a, (flag == 1) ? 2 : 1));//因为if(r)已经换号了,所以Ass()传flag时要换回来(例:2号换回1号)
}
5. 完整代码
#include <stdio.h>#define LEN 3
#define SIGN1 '*'
#define SIGN2 '#'void menu()
{printf("*************\n");printf("***0. exit***\n");printf("***1. play***\n");printf("*************\n");printf("请输入:>");
}
void Init(char a[LEN][LEN])
{for (int i = 0; i < LEN; i++)for (int j = 0; j < LEN; j++)a[i][j] = ' ';
}
void Print(char a[LEN][LEN])
{printf("\n ");for (int i = 0; i < LEN; i++)printf("%d ", i);printf("\n");for (int i = 0; i < LEN; i++){printf("%d ", i);for (int j = 0; j < LEN; j++){printf("%c ", a[i][j]);}printf("\n");}printf("\n");
}
int Set(char a[LEN][LEN], int x, int y, int flag)
{if ((a[x][y] == SIGN1 || a[x][y] == SIGN2) ||(x < 0 || x >= LEN) ||(y < 0 || y >= LEN)){printf("坐标有误,重新输入\n");//落子失败return 0;}//若是1号则给SIGN1a[x][y] = (flag == 1) ? SIGN1 : SIGN2;//落子成功return 1;
}
int Ass(char a[LEN][LEN], int flag)
{//先判断落子后有无获胜者char c = (flag == 1) ? SIGN1: SIGN2;if ((a[0][0] == c && a[0][1] == c && a[0][2] == c) ||(a[1][0] == c && a[1][1] == c && a[1][2] == c) ||(a[2][0] == c && a[2][1] == c && a[2][2] == c) ||(a[0][0] == c && a[1][0] == c && a[2][0] == c) ||(a[0][1] == c && a[1][1] == c && a[2][1] == c) ||(a[0][2] == c && a[1][2] == c && a[2][2] == c) ||(a[0][0] == c && a[1][1] == c && a[2][2] == c) ||(a[0][2] == c && a[1][1] == c && a[2][0] == c)){printf("%d号获胜\n\n", flag);//有人获胜则返回0,game()终止return 0;}//若无人获胜则判断棋盘是否已满,满了则返回0,game()终止int f = 0;for (int i = 0; i < LEN; i++){for (int j = 0; j < LEN; j++){if (a[i][j] != SIGN1 && a[i][j] != SIGN2){//若发现还有为落子的地方则提前breakf = 1;break;}}//提前breakif (f)break;}//若f棋盘已满则返回0if (f == 0){printf("平局\n\n");return 0;}//没人获胜,棋盘未满,游戏继续,返回1return 1;
}
void game()
{char a[LEN][LEN];Init(a);Print(a);//1号先手int flag = 1;do{int x, y;//判断几号落子,给出提示if (flag == 1)printf("1号落子%c坐标:>", SIGN1);else if (flag == 2)printf("2号落子%c坐标:>", SIGN2);scanf("%d %d", &x, &y);int r = Set(a, x, y, flag);//落子成功,则换人if (r)flag = (flag == 1) ? 2 : 1;Print(a);} while (Ass(a, (flag == 1) ? 2 : 1));//因为if(r)已经换号了,所以Ass()传flag时要换回来(例:2号换回1号)
}
int main()
{int input = 0;do{menu();scanf("%d", &input);switch (input){case 0:printf("退出游戏\n");break;case 1:game();break;default:printf("输入错误, 重新输入\n");break;}} while (input);return 0;
}