游戏规则要求:电脑(随机)和玩家一次下一子,双方轮流交替下子,直到电脑和玩家任意一方获胜,或者棋盘满了,结束游戏。
获胜判定:只要电脑或者玩家任意一方的棋子有三子连在一起,可以为横连、纵连、斜连,则该方获胜,游戏结束。若棋盘满了,则判定为平局。
实现程序的思路:首先我们需要定义游戏菜单和游戏规则。
游戏菜单:选择是否开始玩儿游戏,1:玩儿,0:退出游戏;
游戏规则:电脑先走,玩家后走,一方棋子有三子连在一起即为赢,否则棋盘满还未有一方赢判定为平局。
接下来就是开始玩儿游戏了(游戏过程):打印棋盘 → 电脑走一步 → 玩家走一步 → 判定输赢 or 平局 。(为了最后的显示效果,任意一方走一步就打印一次棋盘)。
棋盘初始化 → 打印棋盘 → 设定棋盘的行列数 → 打印盘的样式;
电脑走 → 设定电脑走的随机坐标(棋盘上有空位才能走);
玩家走 → 输入家走的坐标 → 有空位就打印出棋子(还需要考虑坐标被占用和输入坐标不合法两种情况);
判断输赢 → 棋盘上的横连、纵连、斜连有三子一样的即为该方赢 → 棋盘满了即为平局。
开始写代码并进行调试。根据分析写出需要用到的函数,定义出头文件 game.h 的内容:
//game.h
#ifndef __GAME_H___
#define __GAME_H__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3 //定义棋盘的行
#define COL 3 //定义棋盘的列
void InitBoard( char board[ROW][COL], int row, int col); //初始化棋盘
void DisplayBoard( char board[ROW][COL], int row, int col); //打印棋盘
void ComputerMove( char board[ROW][COL], int row, int col); //电脑走
void PlayerMove( char board[ROW][COL], int row, int col); //玩家走
int IsFull(char board[ROW][COL], int row, int col); //定义函数判断棋盘是否满了
char IsWin(char board[ROW][COL], int row, int col); //定义判断输赢或者平局的函数
#endif //__GAME_H__
打印菜单和定义函数规则,写在 test.c 文件里:
//test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
//定义游戏菜单
void menu()
{
printf("*********************\n");
printf("***** 1. play *****\n");
printf("***** 0. exit *****\n");
printf("*********************\n");
}
//定义游戏规则
void game()
{
char board[ROW][COL] = {0}; //创建二维数组并初始化
char ret = '0';
InitBoard(board, ROW, COL); //初始化棋盘
DisplayBoard(board, ROW, COL); //打印棋盘
do
{
printf("电脑走:\n");
ComputerMove(board, ROW, COL); //电脑走,走一步打印一次棋盘
DisplayBoard(board, ROW, COL);
if(ret = IsWin(board, ROW, COL) != ' ')
{
break;
}
printf("玩家走:\n"); //电脑先走,电脑走完玩家走,走一步打印一次棋盘
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
}
while(ret == ' ');
//判断输赢及平局 ,Q--平局, *--电脑赢,X--玩家赢
if(IsWin(board, ROW, COL) == 'Q')
{
printf("平局\n");
}
else if(IsWin(board, ROW, COL) == 'X')
{
printf("玩家赢\n");
}
else if(IsWin(board, ROW, COL) == '*')
{
printf("电脑赢\n");
}
}
//主函数
int main()
{
int input = 0;
srand((unsigned int)time(NULL)); //生成随机数
do
{
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch(input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择:\n");
}
}
while(input);
system("pause");
return 0;
}
设定游戏规则,写在 game.c 文件里,进行棋盘初始化,设定棋盘样式,设定电脑玩家的走法,判定输赢及棋盘是否满了:
//game.c
#define _CRT_SECURE_NO_WARNINGS 1
#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] = ' ';
}
}
}
//打印棋盘
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");
}
}
}
//电脑走
void ComputerMove( char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while(1)
{
x = rand()%row; //输入电脑走的坐标
y = rand()%col;
if(board[x][y] == ' ') //如果棋盘上有空位,电脑就可以随机产生棋子用 '*'表示
{
board[x][y] = '*';
break;
}
}
}
//玩家走
void PlayerMove( char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while(1)
{
printf("请输入坐标:");
scanf("%d%d", &x,&y);
if(x>=1 && x<=row && y>=1 && y<=col) //对玩家来说棋盘的第一行即为1,对程序员来说棋盘的第一行为0
{
if(board[x-1][y-1] == ' ')
{
board[x-1][y-1] = 'X'; //玩家的棋子用 'X'表示
break;
}
else
printf("坐标被占用,请重新输入\n");
}
else
printf("坐标不合法,请重新输入\n");
}
}
//判断棋盘是否满了,没有空位即为满了
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;
int j = 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][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[0][j];
}
if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ' ) //主对角线三个棋子一样
return board[1][1];
else if(board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ' ) //辅对角线三个棋子一样
return board[1][1];
else if(IsFull(board, row, col)) //棋盘满了即为平局
return 'Q';
else
return ' ';
}
运行结果: