【C语言】经典小游戏--三子棋(井字棋)平民版VS豪华版
程序员文章站
2022-05-19 15:02:24
...
致读者:
三子棋(井字棋)---记得小时候经常玩的就是这个游戏,虽然不是多么高大尚,但也饶有趣味!
emmmmmm.......大概就是这个样子吧
这个小游戏你还知道怎样玩吗?我们一起简单回顾一下:
将三子棋看作3x3的一个二维数组,由玩家和电脑分别填充这个数组。当行、列、叉能够达到三连时,就判断输赢。
默认玩家先行且棋子为 ‘ X ’,电脑后手棋子为 ‘ 0 ’。
《平民版》代码如下:
//项目名称:三子棋小游戏
//创建日期:2.18.4.17
//创建者: Mr.Yao
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
enum NUMBER //枚举类型
{
EXIT,
PLAY
};
void Printf(char a[3][3]) //打印数组也就是打印每个操作后的状态
{
int i = 0, j = 0;
for (i = 0; i<3; i++)
{
for (j = 0; j<3; j++)
{
printf("%c ", a[i][j]);
}
printf("\n");
}
}
void menu() //菜单
{
printf("##############1.开始游戏##############\n");
printf("##############0.退出游戏##############\n");
}
void fill(char a[3][3]) //填充 即玩家和电脑进行‘下棋子’
{
int x = 0, y = 0; //分别表示 玩家输入的横坐标和纵坐标
int ran1 = 0, ran2 = 0; //分别表示 电脑产生的连个随机数 用来确定电脑下子的坐标
srand((unsigned)time(NULL));//随机数发生器的初始化函数。
while (1)
{
x = 0, y = 0; //在玩家每次下子前初始化坐标为00
printf("请输入你的坐标:");
scanf("%d%d", &x, &y);
if (x>3 || x<1 || y>3 || y<1)//玩家所输入的横纵坐标都必须要在1-3之间
{
printf("坐标有误,请重新输入!\n");
continue;
}
if (a[x - 1][y - 1] == '_') //数组初始化每个元素为_ 为真时说明该坐标还未被填充
{
a[x - 1][y - 1] = 'X';
Check(a); //检查是否获胜
}
else
{
printf("已被填充,请重新填充!\n");
continue;
}
while ((a[ran1 - 1][ran2 - 1] != '_')) //一直产生随机数直到 该坐标未被填充
{
ran1 = rand() % 3 + 1;
ran2 = rand() % 3 + 1;
}
a[ran1 - 1][ran2 - 1] = '0'; //电脑下子
Check(a);
Printf(a); //双方下完一次后打印出结果
}
}
int Check(char a[3][3])
{
int i, j;
int count = 0; //用来标记数组中未被填充的元素个数
//共8中获胜可能
if (a[0][0] == a[0][1] && a[0][1] == a[0][2] && a[0][2] == 'X'
|| a[1][0] == a[1][1] && a[1][1] == a[1][2] && a[1][2] == 'X'
|| a[2][0] == a[2][1] && a[2][1] == a[2][2] && a[2][2] == 'X'
|| a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] == 'X'
|| a[2][0] == a[1][1] && a[1][1] == a[0][2] && a[0][2] == 'X'
|| a[0][0] == a[1][0] && a[1][0] == a[2][0] && a[2][0] == 'X'
|| a[0][1] == a[1][1] && a[1][1] == a[2][1] && a[2][1] == 'X'
|| a[0][2] == a[1][2] && a[1][2] == a[2][2] && a[2][2] == 'X')
{
printf("玩家赢!\n");
system("pause");
Printf(a);
exit(0);
}
else if (a[0][0] == a[0][1] && a[0][1] == a[0][2] && a[0][2] == '0'
|| a[1][0] == a[1][1] && a[1][1] == a[1][2] && a[1][2] == '0'
|| a[2][0] == a[2][1] && a[2][1] == a[2][2] && a[2][2] == '0'
|| a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] == '0'
|| a[2][0] == a[1][1] && a[1][1] == a[0][2] && a[0][2] == '0'
|| a[0][0] == a[1][0] && a[1][0] == a[2][0] && a[2][0] == '0'
|| a[0][1] == a[1][1] && a[1][1] == a[2][1] && a[2][1] == '0'
|| a[0][2] == a[1][2] && a[1][2] == a[2][2] && a[2][2] == '0')
{
printf("电脑赢!\n");
Printf(a);
system("pause");
exit(0);
}
else
{
for (i = 0; i<3; i++)
{
for (j = 0; j<3; j++)
{
if (a[i][j] == '_')
count++;
}
}
if (count == 0)
{
printf("和棋!\n");
Printf(a);
system("pause");
exit(0);
}
count = 0;
}
}
void init(char arr[3][3])
{
int i = 0, j = 0;
char arry[3][3] = { "___", "___", "___" };
for (i = 0; i<3; i++)
{
for (j = 0; j<3; j++)
{
arr[i][j] = arry[i][j];
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
void PlayGame(char arr[3][3])
{
init(arr);
fill(arr);
}
int main()
{
char game[3][3] = { 0 };
int choose = 1;
while (choose)
{
menu();
printf("请选择:");
scanf("%d", &choose);
switch (choose)
{
case PLAY:
PlayGame(game);
break;
case EXIT:
return 0;
break;
default:
printf("输入错误\n");
break;
}
}
system("pause");
return 0;
}
示图如下:
《豪华版》代码如下:
game.h:
//项目名称:三子棋
//编译环境:VS 2013
//创建时间:2018.4.20
#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
typedef unsigned int uint;
enum APP
{
EXIT,
START
};
#define ROW 3
#define COL 3
void InitBoard(char board[ROW][COL], int row, int col);
void PrintBoard(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);
char is_win(char board[ROW][COL], int row, int col);
#endif //__GAME_H__
game.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col)
{
memset(board, ' ', sizeof(char)* row*col);
}//memset函数用来对一段内存空间全部设置为某个字符
void PrintBoard(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 != 2)
{
printf("---|---|---\n");
}
}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("请输入落子的坐标:\n");
while (1)
{
scanf("%d%d", &x, &y);
//保证输入坐标的合法性,玩家输入的坐标是从1开始的
if (((x >= 1) && (x <= row)) && ((y >= 1) && (y <= col)))
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = 'X';//玩家落子
break;
}
else
{
printf("该坐标已被占用,请换一个坐标:\n");
}
}
else
{
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;//利用rand函数生成随机坐标
if (board[x][y] == ' ')
{
board[x][y] = '0';
break;
}
}
}
static int is_full(char board[ROW][COL], int row, int col)
//函数is_full只在is_win中被调用,可以加上static改变其链接属性
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}//判断棋盘是否下满了
char is_win(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][2] != ' '))
{
return board[i][1];
}
}
for (j = 0; j < col; j++)
{
if ((board[0][j] == board[1][j]) && (board[1][j] == board[2][j]) && (board[2][j] != ' '))
{
return board[1][j];
}
}
if ((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && (board[2][2] != ' '))
{
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 (is_full(board, ROW, COL) == 1)
{
return 'Q';//表示棋盘下满了
}
else
return ' ';
}
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");
printf("*************************\n");
}
void game()
{
char ret;
char board[ROW][COL];
InitBoard(board, ROW, COL);
PrintBoard(board, ROW, COL);
while (1)
{
printf("玩家走:\n");
PlayerMove(board, ROW, COL);
PrintBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
break;
printf("电脑走:\n");
ComputerMove(board, ROW, COL);
PrintBoard(board, ROW, COL);
ret = is_win(board, ROW, COL);
if (ret != ' ')
break;
}
if (ret == 'X')
{
printf(" 你赢了!\n");
}
else if (ret == '0')
{
printf(" 你输了\n");
}
else if (ret == 'Q')
{
printf("平局\n");
}
}
void test()
{
int input = 0;
srand((uint)time(NULL));
do {
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case START:
game();
break;
case EXIT:
break;
default:
break;
}
} while (input);
}
int main()
{
test();
system("pause");
return 0;
}
示图如下:
不正之处,多多指正!
上一篇: Laravel 6常用操作详解
下一篇: PYTHON内置数据结构 之 DICT