三子棋小游戏设计
设计思路大致如下:
将游戏函数与主函数分块,主函数需要调用另一个源文件里的游戏函数,则在自定的头文件里要做好声明,头文件如下
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define ROW 3 //设定棋盘的行列 需要时候直接修改自定变量就好
#define COL 3
void Initboard(char board[ROW][COL], int row, int col);
void Dispboard(char board[ROW][COL], int row, int col);
void Computer(char board[ROW][COL], int row, int col);
char judge(char board[ROW][COL], int row, int col);
int judgeret(char a);
void Input(char board[ROW][COL], int row, int col);
void table();
void game();
void choose();
int full(int count);
主函数如下
int main()
{
table();
choose();
return 0;
}
table为显示菜单
void table()
{
printf("*************************n");
printf("******* 1.Play ********n");
printf("******* 0.Exit ********n");
printf("*************************n");
}
choose为选择函数(三种可能:1 or 0 or其他数字
在choose中用switch来进入选择,1则进入游戏函数本体,0则选择结束程序运行,其他数字default则要求重新输入数字,所以涉及到一个循环问题,就用while死循环来解决。
除了0结束运行的情况,其他都死循环,代码如下
void choose()
{
int flag = 1;
while (flag)
{
printf("Plz input 1 to play or 0 to quit :");
int i = 0;
scanf("%d", &i);
switch (i)
{
case 1:
game();
break;
case 0:
printf("Game over.");
flag = 0;
break;
default:
printf("Plz try again.");
break;
}
}
}
然后进入游戏函数的设计:设定一个3*3的棋盘用来拜访棋子(初始化棋盘函数 = 初始化二维数组
void Initboard(char board[ROW][COL],int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
}
棋子用二维数组的方式进行存放(输入函数
同样是通过while (1) + break的方式实现输入错误后的重新输入。
每回输入完成都打印表盘。
void Input(char board[ROW][COL], int row, int col, int count)
{
printf("Plz input two numbers : ");
while (1)
{
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("Incorrect. Plz try again : ");
}
}
count++;
Dispboard(board, ROW, COL);
电脑输入函数
用rand%ROW的方式获得0到2的随机值,同样当一次随机值不满足输入条件时候,需要又循环来支撑重新输入。
void Computer(char board[ROW][COL], int row, int col, int count)
{
printf("Computer's turn : n");
srand((size_t)time(NULL));
while (1)
{
int x1 = 0;
int y1 = 0;
x1 = rand() % ROW;
y1 = rand() % COL;
if (board[x1][y1] == ' ')
{
board[x1][y1] = '#';
break;
}
}
count++;
Dispboard(board, ROW, COL);
}
显示棋盘和棋子(输出函数
用if语句来判断是否要在最后一行也输出---
void Dispboard(char board[ROW][COL], int row, int col)
{
int r = 0;
int c = 0;
for (r = 0; r < ROW; r++)
{
for (c = 0; c < COL; c++)
{
if (c < COL-1)
printf(" %c |", board[r][c]);
else
printf(" %c n", board[r][c]);
}
int cd;
if (r < ROW - 1)
{
for (cd = 0; cd < COL; cd++)
{
if (cd < COL - 1)
printf("---|");
else
printf("---n");
}
}
}
}
每都是输入与输出的循环,若没有一方胜利或者棋盘没有下满,都继续循环。所以每一方下棋后都需要判断一次是否有上述两种情况。
void game()
{
char board[ROW][COL] = { 0 };
int row = 0;
int col = 0;
Initboard(board, ROW, COL); //初始化表盘
Dispboard(board, ROW, COL); //打印表盘
int count = 0; //用于计算棋子是否下满,每一个玩家或者电脑下棋后都++
while (1)
{
Input(board, ROW, COL,count);
if (judgeret(judge(board, ROW, COL, count)) == 0)
{
break;
}
Computer(board, ROW, COL, count);
if (judgeret(judge(board, ROW, COL, count)) == 0)
{
break;
}
}
}
判断函数如下
先是judge判断是胜利、平局(需要结束循环的情况)还是都没有(需要继续循环的额情况),各自输出一个字符。
再用judgeret函数分析judge输出的字符来决定怎么做,结束则break,继续则不做反应。
char judge(char board[ROW][COL], int row, int col, int count)
{
int g = 0;
for (g = 0; g < ROW; g++)
{
if (board[0][g] == board[1][g] && board[0][g] == board[2][g])
{
return board[0][g];
break;
}//判断列
else if (board[g][0] == board[g][1] && board[g][0] == board[g][2])
{
return board[g][0];
break;
}//判断行
}//行列都判断完了
if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
return board[0][0];
}//判断对角线
else if (board[0][2] == board[1][1] && board[0][2] == board[2][0])
{
return board[0][2];
}//判断对角线2
else if (full(count) == 9)
{
return 'D';
}//判断是否和局
else
{
return 'C';
}//都不是就继续
}
int judgeret(char a)
{
if (a == '*')
{
printf("Congrats!n");
return 0;
}
else if (a == '#')
{
printf("Pity! You lose.n");
return 0;
}
else if (a == 'D')
{
printf("Draw!");
return 0;
}
else if (a == 'C')
{
return 1;
}
}
int full(int count)
{
if (count == 9)
return 9;
else
return 0;
}
这样下来就基本完成了简单的游戏。
可改进方向也有很多:
*在判断输赢的函数里限定死了数组的位数,即使改变定义的ROW和COL也不能改变里面的值
*电脑输入不够聪明,完全随机,有时候让棋电脑都赢不了
*和局的判断情况可以改进,有的时候不一定要下完才能判断和局,可能下到7个8个这盘棋就死了