实现三子棋:
- test.c //测试游戏的逻辑
- game.c //游戏代码的实现
- game.h //游戏代码的声明(函数声明、符号定义)
逻辑:
①游戏至少进入一次(打印菜单) --> do…while
结构
②玩家输入0:显示退出游戏; 输入1:进入游戏game()
; 输入其他数字:显示选择错误 --> switch
语句
③玩游戏:game()
函数
-
打印棋盘(3 × 3) --> 创建二维数组
board[ROW][COL]
拓:为了方便后期将三子棋 改为 五子棋、十子棋…… >> game.h
#define ROW 3 #define COL 3
-
棋盘每格需存储一个空格 --> 初始化棋盘的函数
InitBoard()
//函数声明 >> game.h void InitBoard(char board[3][3], int cow, int col); //函数定义 >> game.c void InitBoard(char board[ROW][COL], int cow, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ''; } } }
-
打印棋盘(一组数据,一个分割行) -->
DisplayBoard()
函数//版本1 - 固定的行、列 void DisplayBoard(char board[ROW][COL], int row, int col); void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { //打印数据 printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]); //打印分割数据 if(i < row - 1) printf("---|---|---\n"); } } //版本2 - 可根据ROW、COL的值打印相应的行、列 //函数声明 >> game.h void DisplayBoard(char board[ROW][COL], int row, int col); //函数定义 >> game.c void DisplayBoard(char board[ROW][COL], int row, int col) { int i = 0; for (i = 0; i < row; i++) { //打印数据 int j = 0; for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //打印分割数据 if (i < row - 1) { int j = 0; for (j = 0; j < col; j++) { printf("---"); if (j < col - 1) printf("|"); } printf("\n"); } } }
-
玩家下棋,输入下棋的坐标(判断玩家输入的坐标是否合法) -->
PlayerMove()
函数1.坐标超出棋盘:输出“坐标被占用,不能下棋,请选择其他位置”并让玩家重新输入
2.坐标输入无误:(用*标记玩家输入坐标)
//函数声明 >> game.h void PlayerMove(char board[ROW][COL], int row, int col); //函数定义 >> game.c void PlayerMove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("玩家下棋:>"); while (1) { printf("请输入下标:>"); scanf("%d %d", &x, &y); //坐标范围合法的判断 if (x >= 1 && x <= row && y >= 1 && y <= col) { //判断坐标是否重复 if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else printf("坐标被占用,不能下棋,请选择其他位置"); } else { printf("坐标非法,请重新输入\n"); } } }
-
电脑下棋,同时保留玩家下棋的位置(判断玩家输入的坐标是否合法) -->
ComputerMove
//函数声明 >> game.h void ComputerMove(char board[ROW][COL], int row, int col); //函数定义 >> game.c void ComputerMove(char board[ROW][COL], int row, int col) { printf("电脑下棋:>\n"); //生成下标 int x = 0; int y = 0; while (1) { x = rand() % row; //0~2 y = rand() % col; //0~2 if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } int main() { //设置随机数的生成起点,将返回值类型强制转化为unsigned int srand((unsigned int)time(NULL)); }
-
判断输赢 -->
IsWin
函数玩家嬴 - ’ * ’
电脑赢 - ’ # ’
平局 - ’ Q ’
继续 - ’ C ’//函数声明 >> game.h char IsWin(char board[ROW][COL], int row, int col); //函数定义 >> game.c //棋盘满了返回1 //不满 返回0 int IsFull(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++) { if (board[i][j] == ' ') { return 0; } } } return 1; } //判断输赢 char IsWin(char board[ROW][COL], int row, int col) { //行 int i = 0; for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ') { return board[i][1]; } } //列 int j = 0; for (j = 0; j < col; j++) { if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ') { return board[1][j]; } } //对角线 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ') { return board[1][1]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ') { return board[1][1]; } //没有人嬴 - 平局 if (IsFull(board, row, col)) { return 'Q'; } //游戏继续 return 'C'; } //主逻辑 >> test.c void game() { //下棋 while (1) { PlayerMove(board,ROW,COL); //判断输赢 ret = IsWin(board, ROW, COL); if (ret != 'C') { break; } DisplayBoard(board, ROW, COL); ComputerMove(board, ROW, COL); //判断输赢 ret = IsWin(board, ROW, COL); if (ret != 'C') { break; } DisplayBoard(board, ROW, COL); } if (ret == '*') { printf("玩家嬴\n"); } else if (ret == '#') { printf("电脑嬴\n"); } else { printf("平局\n"); } DisplayBoard(board, ROW, COL); // 输出最终棋盘落子情况 }
完整代码:
>> test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("*********************************\n");
printf("******* 1.play 0.exit *******\n");
printf("*********************************\n");
}
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 };
//初始化棋盘的函数
InitBoard(board, ROW, COL);
//打印棋盘:本质打印数组数据
DisplayBoard(board, ROW, COL);
//下棋
while (1)
{
PlayerMove(board,ROW,COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
ComputerMove(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
DisplayBoard(board, ROW, COL);
}
if (ret == '*')
{
printf("玩家嬴\n");
}
else if (ret == '#')
{
printf("电脑嬴\n");
}
else
{
printf("平局\n");
}
DisplayBoard(board, ROW, COL);
}
int main()
{
srand((unsigned int)time(NULL)); //设置随机数的生成起点,将返回值类型强制转化为unsigned int
int input = 0;
do
{
menu(); //打印菜单
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}
>> game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//初始化棋盘
void InitBoard(char board[3][3], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
//玩家嬴 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col);
>> game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//-----------打印棋盘--------------
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] = ' ';
}
}
}
//版本1 - 固定的行、列
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
// int i = 0;
// for (i = 0; i < row; i++)
// {
// //打印数据
// printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
// //打印分割数据
// if(i < row - 1)
// printf("---|---|---\n");
// }
//}
//版本2 - 可根据ROW、COL的值打印相应的行、列
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//打印数据
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
//打印分割数据
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("\n");
}
}
}
//-------------玩家下棋-----------------
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋:>");
while (1)
{
printf("请输入下标:>");
scanf("%d %d", &x, &y);
//坐标范围合法的判断
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//判断坐标是否重复
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
printf("坐标被占用,不能下棋,请选择其他位置");
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
//电脑下棋
//找没有下棋的位置随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:>\n");
//生成下标
int x = 0;
int y = 0;
while (1)
{
x = rand() % row; //0~2
y = rand() % col; //0~2
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//棋盘满了返回1
//不满 返回0
int IsFull(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++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
//判断输赢
char IsWin(char board[ROW][COL], int row, int col)
{
//行
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
{
return board[i][1];
}
}
//列
int j = 0;
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
{
return board[1][j];
}
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//没有人嬴 - 平局
if (IsFull(board, row, col))
{
return 'Q';
}
//游戏继续
return 'C';
}