天啦噜,在电脑上也可以玩的三子棋小游戏(含优化)
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。
准备工作
我将游戏的骨架放到test.c中
把相关游戏的实现放到game.c中
相关思路如图
三子棋游戏思路:
1、至少玩一次,可以玩多次,运用do…while循环
2、进入游戏后先打印菜单
3、提示用户输入,根据输入值来确定选择的游戏进程(1代表玩游戏,2代表退出,其他需要重新输入并选择)
我们需要知道三子棋的一些信息:
- 三子棋形状
打印出的棋盘:
- 游戏规则:只要将自己的三个棋子走成一条线,对方就算输了。
所以获胜·有三种情况:1、横排三子 2、竖排三子 3、对角线三子
三子棋游戏实现具体思路:
1.我们要记录下棋的结果,就需要对应的二维数组来存储
2.创建的二维数组要进行初始化,全部赋值成空格
3.打印棋盘,看一下展示的效果
4.玩家下棋
5.判断玩家是否游戏胜利 判断游戏状态是否继续
6.电脑下棋(随机落子的方式)
7.判断电脑是否游戏胜利 判断游戏状态是否继续
游戏共有四种状态: 玩家赢,电脑赢,平局,继续 |
可优化点
1.电脑下棋,将随机走变成有策略走,让电脑看起来更像“玩家”。(代码中实现了这个优化)
2.我们可以优化为更加好玩的五子棋,比如说后续ROW,COL都改成5。为了让ROW,COL在变化调整后依然适用,我们可以对其进行相应的优化。(本次代码暂未实现该优化)
优化1实现:
思路:这个优化的实现注意考虑两个方面的内容:
1、如果电脑落子,有机会直接赢,则优先落在能赢的坐标上
2、如果玩家落子有机会赢,拦截玩家路子坐标(步骤1优先级高于步骤2)
3、如果步骤1、步骤2均不满足,电脑继续伪随机落子
源码提供
gittee码云源代码
完整代码:
源文件 text.c文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()//打印菜单
{
printf("********************************************\n");
printf("*********** 1.play ***************\n");
printf("*********** 2.exit ***************\n");
printf("********************************************\n");
}
void game()
{ //存储数据
char board[ROW][COL];
//初始化棋盘
Inboard(board, ROW, COL);
//打印棋盘,本质上是数组
Displayboard(board, ROW,COL);
//接收游戏状态
int ret = 0;
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
Displayboard(board, ROW, COL);
//判断玩家输赢
ret=IsWin(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
ComputerMove(board, ROW, COL);
Displayboard(board, ROW, COL);
//判断电脑输赢
ret=IsWin(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
{
printf("玩家获胜\n");
}
else if (ret == '#')
{
printf("电脑获胜\n");
}
else
{
printf("双方取得平局\n");
}
Displayboard(board, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("退出游戏\n");
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input!=2);
return 0;
}
源文件game.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"game.h"
void Inboard(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;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ",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 PlayerMove(char board[ROW][COL],int row,int col)//玩家下棋
{
int x = 0;
int y = 0;
printf("玩家下棋:>\n");
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("坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标输入错误,请重新输入\n");
}
}
}
//int defence_player(char board[ROW][COL], int row, int col/*, int k*/)//判断玩家是否有机会赢,如果能赢就堵住他
//{
// int i = 0;
// int j = 0;
// int k = 0;
// while (k==0)
// {
// //判断玩家在横行上是否会赢
// for (i = 0; i < row; i++)
// {
// if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
// {
// board[i][2] = '#';
// k = 1;
// break;
// }
//
//
// if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
// {
// board[i][1] = '#';
// k = 1;
// break;
// }
//
//
// if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
// {
// board[i][0] = '#';
// k = 1;
// break;
// }
// }
// if (k != 0)
// break;
//
// //判断玩家在竖列上是否会赢
// for (j = 0; j < col; j++)
// {
// if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
// {
// board[2][j] = '#';
// k = 1;
// break;
// }
//
//
// if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
// {
// board[1][j] = '#';
// k = 1;
// break;
// }
//
//
// if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
// {
// board[0][j] = '#';
// k = 1;
// break;
// }
// }
// break;
// }
//
// //判断玩家在对角线上是否会赢,又加了一个while是为了让判断对角线的代码成块。
// while (k==0)
// {
// if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
// {
// board[2][2] = '#';
// k = 1;
// break;
// }
//
//
// if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
// {
// board[1][1] = '#';
// k = 1;
// break;
// }
//
//
// if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
// {
// board[0][0] = '#';
// k = 1;
// break;
// }
//
//
// if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
// {
// board[2][0] = '#';
// k = 1;
// break;
// }
//
//
// if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
// {
// board[1][1] = '#';
// k = 1;
// break;
// }
//
//
// if (board[1][1] == board[2][0] && board[2][0] == '*' && board[0][2] == ' ')
// {
// board[0][2] = '#';
// k = 1;
// break;
// }
// break;
// }
// return k;//返回值如果是1那么已经对玩家进行了堵截,如果是0则无需堵截。
//}
//
//int attack_computer(char board[ROW][COL], int row, int col)//判断电脑下一步落子能否赢游戏
//{
// int i = 0;
// int j = 0;
// int k = 0;
// while (k == 0)
// {
// //判断电脑行排能否赢
// for (i = 0; i < row; i++)
// {
// if (board[i][0] == board[i][1] && board[i][0] == '#' && board[i][2] == ' ')
// {
// board[i][2] = '#';
// k = 1;
// break;
// }
// if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
// {
// board[i][1] = '#';
// k = 1;
// break;
// }
// if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
// {
// board[i][0] = '#';
// k = 1;
// break;
// }
// }
// if (k != 0)//落子后跳出
// break;
// //判断电脑列排能否赢
// for (j = 0; j < col; j++)
// {
// if (board[0][j] == board[1][j] && board[0][j] == '#' && board[2][j] == ' ')
// {
// board[2][j] = '#';
// k = 1;
// break;
// }
// if (board[0][j] == board[2][j] && board[0][j] == '#' && board[1][j] == ' ')
// {
// board[1][j] = '#';
// k = 1;
// break;
// }
// if (board[2][j] == board[1][j] && board[0][j] == '#' && board[0][j] == ' ')
// {
// board[0][j] = '#';
// k = 1;
// break;
// }
// }
// break;
// }
// //判断电脑对角线能否赢
// while (k== 0)
// {
// //左上角到右下角对角线判断
// if (board[0][0] == board[1][1] && board[0][0] == '#' && board[2][2] == ' ')
// {
// board[2][2] = '#';
// k = 1;
// break;
// }
// if (board[0][0] == board[2][2] && board[0][0] == '#' && board[1][1] == ' ')
// {
// board[1][1] = '#';
// k = 1;
// break;
// }
// if (board[1][1] == board[2][2] && board[0][0] == '#' && board[0][0] == ' ')
// {
// board[0][0] = '#';
// k = 1;
// break;
// }
// //左下角到右上角对角线判断
// if (board[2][0] == board[1][1] && board[2][0] == '#' && board[0][2] == ' ')
// {
// board[0][2] = '#';
// k = 1;
// break;
// }
// if (board[2][0] == board[0][2] && board[2][0] == '#' && board[1][1] == ' ')
// {
// board[1][1] = '#';
// k = 1;
// break;
// }
// if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
// {
// board[2][0] = '#';
// k = 1;
// break;
// }
// break;
// }
// k = defence_player(board, row, col, k);
// return k;
//}
//
实现电脑下棋优化
//void Computer_move(char board[ROW][COL], int row, int col)
//{
// int x = 0;
// int y = 0;
// int ret = 0;
// ret = attack_computer(board, row, col);
// while (0 == ret)
// {
// x = rand() % row;
// y = rand() % col;
// if (board[x][y] == ' ')
// {
// board[x][y] = '#';
// break;
// }
// }
//}
void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{
printf("电脑下棋:>\n");
while (1)
{
int x = rand() % row;
int y = rand() % col;
//判断坐标是否被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int IsFull(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
count++;
}
}
}
if (count == 0)//棋盘满了返回1,不满返回0
return 1;
else
return 0;//棋盘没满
return 1;
}
int 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][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][i];
}
}
//对角线
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];
}
//判断平局
int ret = IsFull(board, row, col);
if (ret == 1)
{
return 'Q';
}
return 'C';
}
game.c中间部分注释为优化 |
头文件game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
//初始化棋盘
void Inboard(char board[ROW][COL],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);
//判断输赢
int IsWin(char board[ROW][COL], int row, int col);
//堵截玩家
int defence_player(char board[ROW][COL], int row, int col, int k);
//电脑进攻
int attack_computer(char board[ROW][COL], int row, int col);
//1. 玩家赢了 - *
//2. 电脑赢了 - #
//3. 平局 - Q
//4. 游戏继续 - C