三子棋游戏详解
1.创造一个三子棋游戏的框图界面
2.让玩家落子
3.电脑落子
4.判断玩家胜利还是电脑胜利,还是和棋
整体思路:我们首先创造一个界面函数来布置游戏框图,当玩家落完子之后,我们检查一下玩家是否胜利,再来检查游戏结果是否为和棋,当电脑落完子之后,我们在检查一下电脑是否胜利
(我们的框图是奇数个,所以如果结果是和棋,那么最后一个落子的肯定是玩家,因此我们在玩家落完子之后,应当检查一下是否和棋)
1.布置界面框图的函数(定义二维数组,并初始化)
void Init()
{
for (int row = 0; row < ROW; row++)
for (int col = 0; col < COL; col++)
{
g_chess_board[row][col] = ' ';
}
Print();
}
void Print()
{
for (int row = 0; row < ROW; row++)
{
printf("%c|%c|%c \n", g_chess_board[row][0], g_chess_board[row][1], g_chess_board[row][2]);
if (row != 2)
{
printf("-|-|-\n");
}
}
}
2.玩家落子
//2.玩家落子,玩家的棋用x表示
//提示玩家落子
//判断玩家输入的坐标,如果坐标比三大或者比零小或者坐标位置已被占用,则提示玩家输入错误,
//玩家重新输入坐标,直到输入的坐标合理,
//如果输入的坐标合理,该坐标就被赋值x,跳出循环,
//打印
void UsePlay()
{
while (1)
{
printf("请输入一个坐标");
int row;
int col;
scanf("%d %d", &row, &col);
if (row >= ROW || row<0 || col >= COL || col < 0 || g_chess_board[row][col] != ' ')
{
printf("输入有误,请重新输入\n");
}
else
{
g_chess_board[row][col] = 'x';
Print();
break;
}
}
}
3.电脑落子
//5.电脑落子,电脑落子用o表示
//产生两个随机数作为电脑落子的坐标
//判断电脑产生的坐标,如果该坐标比零小或者比三大或者坐标已被占用,
//电脑重新产生两个坐标,直到产生的坐标合理
//如果坐标合理,该坐标被赋值o,出循环
//打印
void ComputerPlay()
{
srand(time(NULL));
while (1)
{
int row = rand() % 3;
int col = rand() % 3;
if (row < ROW && row >= 0 && col >= 0 && col<COL && g_chess_board[row][col] == ' ')
{
g_chess_board[row][col] = 'o';
Print();
break;
}
}
}
4.判断玩家胜利(电脑胜利的判断方法类似)
int UseWin()
{
int row;
int col;
for (row = 0; row <ROW; row++)
{
if (g_chess_board[row][0] == g_chess_board[row][1] && g_chess_board[row][0] == g_chess_board[row][2] && g_chess_board[row][0] == 'x')
return 1;
}
for (col = 0; col <COL; col++)
{
if (g_chess_board[0][col] == g_chess_board[1][col]
&& g_chess_board[0][col] == g_chess_board[2][col]
&& g_chess_board[0][col] == 'x')
return 1;
}
if (g_chess_board[0][0] == g_chess_board[1][1] && g_chess_board[0][0] == g_chess_board[2][2] && g_chess_board[0][0] == 'x')
{
return 1;
}
if (g_chess_board[0][2] == g_chess_board[1][1] && g_chess_board[0][2] == g_chess_board[2][0] && g_chess_board[0][2] == 'x')
{
return 1;
}
return 0;
}
5.和棋的判断
//4.和棋1
//如果棋盘是满的,那么那么最后一个落子的是玩家,所以在判断完玩家赢之前,就应该检查是否是和棋
//如果棋盘已满,则上方打成平局,和棋,跳出循环
int DrawChess()
{
int row;
int col;
for (row = 0; row < ROW; row++)
for (col = 0; col < COL; col++)
{
if (g_chess_board[row][col] == ' ')
{
return 0;
}
}
return 1;
}
程序源代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
//三子棋
//1.定义一个3*3的全局变量二维数组,
char g_chess_board[ROW][COL];
//定义分数变量
int score = 0;
//定义玩家胜利次数
int use_win_count = 0;
//打印
void Print()
{
for (int row = 0; row < ROW; row++)
{
printf("%c|%c|%c \n", g_chess_board[row][0], g_chess_board[row][1], g_chess_board[row][2]);
if (row != 2)
{
printf("-|-|-\n");
}
}
}
//初始化
void Init()
{
for (int row = 0; row < ROW; row++)
for (int col = 0; col < COL; col++)
{
g_chess_board[row][col] = ' ';
}
Print();
}
//2.玩家落子,玩家的棋用x表示
//提示玩家落子
//判断玩家输入的坐标,如果坐标比三大或者比零小或者坐标位置已被占用,则提示玩家输入错误,
//玩家重新输入坐标,直到输入的坐标合理,
//如果输入的坐标合理,该坐标就被赋值x,跳出循环,
//打印
void UsePlay()
{
while (1)
{
printf("请输入一个坐标");
int row;
int col;
scanf("%d %d", &row, &col);
if (row >= ROW || row<0 || col >= COL || col < 0 || g_chess_board[row][col] != ' ')
{
printf("输入有误,请重新输入\n");
}
else
{
g_chess_board[row][col] = 'x';
Print();
break;
}
}
}
//3.判断玩家是否胜利
//如果有一行或者一列是x,或者对角线所在的位置是x,则玩家胜利,跳出循环
//否则继续执行下一条语句
int UseWin()
{
int row;
int col;
for (row = 0; row <ROW; row++)
{
if (g_chess_board[row][0] == g_chess_board[row][1] && g_chess_board[row][0] == g_chess_board[row][2] && g_chess_board[row][0] == 'x')
return 1;
}
for (col = 0; col <COL; col++)
{
if (g_chess_board[0][col] == g_chess_board[1][col]
&& g_chess_board[0][col] == g_chess_board[2][col]
&& g_chess_board[0][col] == 'x')
return 1;
}
if (g_chess_board[0][0] == g_chess_board[1][1] && g_chess_board[0][0] == g_chess_board[2][2] && g_chess_board[0][0] == 'x')
{
return 1;
}
if (g_chess_board[0][2] == g_chess_board[1][1] && g_chess_board[0][2] == g_chess_board[2][0] && g_chess_board[0][2] == 'x')
{
return 1;
}
return 0;
}
//4.和棋1
//如果棋盘是满的,那么那么最后一个落子的是玩家,所以在判断完玩家赢之前,就应该检查是否是和棋
//如果棋盘已满,则上方打成平局,和棋,跳出循环
int DrawChess()
{
int row;
int col;
for (row = 0; row < ROW; row++)
for (col = 0; col < COL; col++)
{
if (g_chess_board[row][col] == ' ')
{
return 0;
}
}
return 1;
}
//5.电脑落子,电脑落子用o表示
//产生两个随机数作为电脑落子的坐标
//判断电脑产生的坐标,如果该坐标比零小或者比三大或者坐标已被占用,
//电脑重新产生两个坐标,直到产生的坐标合理
//如果坐标合理,该坐标被赋值o,出循环
//打印
void ComputerPlay()
{
srand(time(NULL));
while (1)
{
int row = rand() % 3;
int col = rand() % 3;
if (row < ROW && row >= 0 && col >= 0 && col<COL && g_chess_board[row][col] == ' ')
{
g_chess_board[row][col] = 'o';
Print();
break;
}
}
}
//6.判断电脑是否胜利
//如果有一行或者一列是o,或者对角线所在的位置是o,则玩家胜利,跳出循环
//否则继续执行下一条语句
int ComputerWin()
{
int row;
int col;
for (row = 0; row <ROW; row++)
{
if (g_chess_board[row][0] == g_chess_board[row][1] && g_chess_board[row][0] == g_chess_board[row][2] && g_chess_board[row][0] == 'o')
return 1;
}
for (col = 0; col <COL; col++)
{
if (g_chess_board[0][col] == g_chess_board[1][col] && g_chess_board[0][col] == g_chess_board[2][col] && g_chess_board[0][col] == 'o ')
return 1;
}
if (g_chess_board[0][0] == g_chess_board[1][1] && g_chess_board[0][0] == g_chess_board[2][2] && g_chess_board[0][0] == 'o')
{
return 1;
}
if (g_chess_board[0][2] == g_chess_board[1][1] && g_chess_board[0][2] == g_chess_board[2][0] && g_chess_board[0][2] == 'o')
{
return 1;
}
return 0;
}
void main()
{
//游戏进行5次
//定义一个玩家胜利的次数变量,定义游戏的分数变量,胜利一次得十分
//当进行完5次游戏时,输出玩家的胜利次数,玩家得分,
int count = 0;
while (++count <= 5)
{
printf("第%d次游戏\n", count);
Init();
while (1)
{
UsePlay();
if (UseWin(g_chess_board))
{
printf("玩家胜利\n");
score += 10;
use_win_count++;
break;
}
if (DrawChess(g_chess_board))
{
printf("和棋\n");
break;
}
ComputerPlay();
if (ComputerWin(g_chess_board))
{
printf("电脑胜利\n");
break;
}
}
}
printf("玩家胜利了:%d次,得分为:%d", use_win_count, score);
system("pause");
}