一、三子棋小游戏程序框架
二、自定义函数功能整体描述
三、游戏各个子功能的实现
功能九的具体游戏流程框架大致如下:
四、遇到的问题和解决方法
序号 | 遇到的问题 | 产生原因 | 解决方法 |
---|---|---|---|
1 | 棋盘第一次打印显示混乱。 | 未认识到棋盘的布局结构和正确输出过程,对数据行和分割行分别使用了两次双重循环。 | 只需要一层外循环控制打印次数就行,打印次数由define定义,里面同级两层循环分别打印数据和分割行。 |
2 | 定义玩家下棋使用了for的双层循环。 | 单纯地只是在判断玩家输入的位置是否空置,如果空置的话,放在内层的break语句跳不出两层循环。 | 改用while循环。 |
3 | 位置被占用,玩家下棋不成功的情况下,电脑还能正常下棋并且显示出来。 | 没有想到玩家下棋不成功应是个循环,直到玩家下棋成功。 | 定义了一个全局变量,用来作为判断玩家是否成功下棋的依据。 |
4 | 玩家上一次下棋失败后,第二次下棋成功,但是游戏不能继续,继续显示该位置被占用了,未继续显示棋盘并且电脑输入。 | 因为第一次棋盘被占用后,全局变量flag的值已经改变,第二次判断棋盘是否占用的时候,当跳出循环时,flag的值仍然是上一次棋盘被占用的值,所以程序还是认为棋盘被占用,要求重新输入。 | 当棋盘有空余这个条件为真的情况下,break语句执行之前,提前给flag赋值为1,这样即便上一次判断结果flag=0,判断结束后,flag值要么会被改变,要么不变,从而才能真正实现在判断一次棋盘占用的情况下之后的判断不受干扰。 |
五、源代码分享交流
文件1:game.h(声明函数)
#pragma once
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
//声明菜单
void menu();
//初始化棋盘
void Init_chess_board(char chess_board[ROW][COL], int row, int col);
//显示棋盘
void Display_chess_board(char chess_board[ROW][COL], int row, int col);//row和col不可用ROW和COL替代
//玩家下棋
void Player_move(char chess_board[ROW][COL], int row, int col);
//电脑下棋
void Computer_move(char chess_board[ROW][COL], int row, int col);
//判断棋局
char Judge_chess_board(char chess_board[ROW][COL], int row, int col);
//棋盘是否已满
int IsFull(char chess_board[ROW][COL], int row, int col);
文件2:game.c(定义函数)
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
extern int flag;
//定义菜单
void menu()
{
printf("********************\n");
printf("*******1、PLAY******\n");
printf("*******0、EXIT******\n");
printf("********************\n");
}
//定义初始化棋盘
void Init_chess_board(char chess_board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
chess_board[i][j] = ' ';
}
}
}
//定义显示棋盘
void Display_chess_board(char chess_board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", chess_board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
if (i < row - 1) {
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\n");
}
}
}
//定义玩家下棋
void Player_move(char chess_board[ROW][COL], int row, int col)
{
printf("玩家下棋\n");
int x = 0, y = 0;
while (1)
{
printf("请输入坐标->");
scanf("%d %d", &x, &y);
if (chess_board[x - 1][y - 1] == ' ')
{
chess_board[x - 1][y - 1] = '*';
flag = 1;
break;
}
else
{
printf("该坐标被占用,请输入其它坐标\n");
flag = 0;
break;
}
}
}
//定义电脑下棋
void Computer_move(char chess_board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋\n");
while(1){
x = rand() % row;
y = rand() % col;
if (chess_board[x][y] == ' ')
{
chess_board[x][y] = '#';
break;
}
}
}
//定义棋盘是否已满
int IsFull(char chess_board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (chess_board[i][j] == ' ')
return 0;
}
}
return 1;
}
//定义判断棋局
char Judge_chess_board(char chess_board[ROW][COL], int row, int col)
{
int k = 0;
//判断每行
for (k = 0; k < row; k++)
{
if (chess_board[k][0] == chess_board[k][1] && chess_board[k][1] == chess_board[k][2] && chess_board[k][0] != ' ')
return chess_board[k][0];
}
//判断每列
for (k = 0; k < row; k++)
{
if (chess_board[0][k] == chess_board[1][k] && chess_board[1][k] == chess_board[2][k] && chess_board[0][k] != ' ')
return chess_board[0][k];
}
//判断主对角线
if (chess_board[0][2] == chess_board[1][1] && chess_board[1][1] == chess_board[2][0] && chess_board[0][2] != ' ')
return chess_board[1][1];
//判断副对角线
if (chess_board[0][0] == chess_board[1][1] && chess_board[1][1] == chess_board[2][2] && chess_board[0][0] != ' ')
return chess_board[1][1];
//判断平局
if (IsFull(chess_board, row, col))
{
return 'E';
}
return 'A';
}
文件3:test.c(功能实现)
#define _CRT_SECURE_NO_WARNINGS 1
//三子棋:
//1、菜单
//2、初始化棋盘内容为空白
//3、显示棋盘(玩家输入后要显示,电脑输入后也要显示)
#include "game.h"
int flag = 1;
void Game()
{
char chess_board[ROW][COL] = { 0 };
int i = 0, j = 0;
char ret = 0;
//初始化棋盘内容为空白
Init_chess_board(chess_board,ROW,COL);
//显示棋盘
Display_chess_board(chess_board, ROW, COL);
while (1) {
//玩家下棋
do {
Player_move(chess_board, ROW, COL);
} while (flag == 0);
//显示棋盘
Display_chess_board(chess_board, ROW, COL);
//判断棋局
ret = Judge_chess_board(chess_board, ROW, COL);
if (ret != 'A')
{
break;
}
//电脑下棋
Computer_move(chess_board, ROW, COL);
//显示棋盘
Display_chess_board(chess_board, ROW, COL);
//判断棋局
ret = Judge_chess_board(chess_board, ROW, COL);
if (ret != 'A')
{
break;
}
}
if (ret == '*')
{
printf("恭喜玩家胜利!\n");
}
else if (ret == '#')
{
printf("不要气馁,再来一局\n");
}
else
printf("平局\n");
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do {
menu();
scanf("%d", &input);
switch (input)
{
case 1:
{
Game();
break;
}
case 0:
{
printf("游戏退出,感谢使用\n");
break;
}
default:
{
printf("请输入0或1:\n");
break;
}
}
} while (input);
return 0;
}