三子棋的C语言实现(详解)
2023-12-15 15:32:08
三子棋的C语言实现(详解)
第一次见到三子棋好像是猪猪侠和菲菲公主,哈哈。
笔者今天学习并用C语言实现了这个简单的小游戏。
中间犯了许多小错误,比如
这个粗心直接跳出循环,也不报错,逐语句查了半天。
又比如do while结尾的分号没写,“=”和“==”
同时笔者也学习了两个新知识
如何产生随机数,rand(),srand()函数的用法
rand以种子为基准(种子是一个数),用一个递推公式算出的一系列数,来产生随机数。种子不变,rand函数产生的随机数是一样的。为了产生“真正的随机数”,用srand函数和time函数根据时间不同随机初始化种子。
srand可以根据不同参数初始化不同的随机数种子,比如在srand(1),srand(2)下,rand()产生的随机数是不同的。但为了“随机”,我们用时间戳,不同时间,srand的参数不一样即重置了种子。这样就达到了随机啦。
注意,
srand((unsigned)time(NULL));
放在循环体外面,重置一次种子就可以了,然后在循环中,rand产生第一个,第二个…随机数。
为什么呢?因为电脑运算速度很快,要是放在循环体里面,在很短的时间内,种子没有被重置,每次循环都打印该时间下对应的第一个随机数,也就是说,会打印相同的数。(笔者初学,错误请大佬指正)
memset函数的使用
memset(&board[0][0],' ',ROW*COL*sizeof(board[0][0]);
用在棋盘初始化中,见下面代码
分文件的代码具体实现和详细注释
//game.h
#include <string.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 PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
char JudgingWin(char board[ROW][COL], int row, int col);
//game.c
#include"game.h"
#include<stdio.h>
//实现
void InitBoard(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++)
{
board[i][j] = ' ';//先都初始化空格,占个位置,不会让棋盘打印歪
}
}
//memset(&board[0][0],' ',ROW*COL*sizeof(board[0][0]);
//从首地址开始赋值空格,连续赋值这么多字节
//包含<string.h>
}
//列固定不能动了
//void DisplayBoard(char board[ROW][COL], int row, int col);
//{
// int i = 0;
// int j = 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 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("|\n");
// }
// if(i<row-1)
// printf(" ---|---|---\n");
//
// }
//}
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("请玩家下棋,输入想要下棋的坐标");
scanf_s("%d %d", &x, &y);//遇到了scanf死循环。。。
//站在用户角度,可没有什么在第零行下棋
if (x > 0 && x <= row && y > 0 && y <= col)
{
//首先看一下坐标有没有被占用
if (board[x - 1][y - 1] == ' ')
{
board[x-1][y-1] = 'O';//玩家的棋子O
}
else
{
printf("该处已经下过棋,请重新输入\n");
}
}
else
{
printf("输入非法坐标,请重新输入\n");
}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋了\n");
while (1)
{
x = rand() % row;//随机产生0,1,2
y = rand() % col;
if (board[x][y] ==' ')
{
board[x][y] = 'X';
break;
}
}
}
char JudgingWin(char board[ROW][COL], int row, int col)
{
//赢有四种情况,谁赢返回谁的棋子字符O或X,平局返回Q,继续返回C
int i = 0;
//第i行字符全部相同(但不能全是空),判赢
for (i = 0;i < row;i++)
{
if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//第i列相同,判赢
for (i = 0;i < col;i++)
{
if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//对角线同,判赢
if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ')
{
return board[0][2];
}
//棋盘已满,无赢则判平局,返回Q;棋盘未满,继续下,返回C
for (i = 0;i < row;i++)
{
int j = 0;
for (j = 0;j < col;j++)
{
if (board[i][j] == ' ')
return 'C';
}
}
return 'Q';
}
//test.c
#include<stdio.h>
#include"game.h"
void menu()
{
printf("****************************************\n");
printf("*********欢迎来玩三子棋游戏!***********\n");
printf("***********输入1.开始游戏***************\n");
printf("***********输入0.退出游戏***************\n");
printf("****************************************\n");
}
void game()
{
//用二维数组来存放数据
char board[ROW][COL] = { 0 };//棋盘board
//初始化棋盘
InitBoard(board, ROW, COL);//方便改棋盘大小
//显示(打印)棋盘
DisplayBoard(board, ROW, COL);
//循环 玩家下棋后,打印棋盘,判断输赢
// 电脑下棋后,打印棋盘,判断输赢
char ret = 0;
//只要返回ret为C,电脑和人就继续下棋
//返回ret为其他值时,跳出循环判断结局
while (1)
{
PlayerMove(board, ROW, COL);//这里是调用函数,传参,可不是什么定义,申明,实现
DisplayBoard(board, ROW, COL);
ret = JudgingWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = JudgingWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == 'Q')
{
printf("已达成平局\n");
}
if (ret == 'O')
{
printf("恭喜!您成功地击溃了电脑\n");
}
if (ret == 'X')
{
printf("悲哀!您狠狠地输给了电脑\n");
}
}
int main()
{
int input = 0;//输入
menu();
srand((unsigned)time(NULL));//重置随机数种子
do
{
scanf_s("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
default:
printf("输入错误,请重新输入");
break;
}
} while (input);//do while这个分号可不能丢!
return 0;
}
文章来源:https://blog.csdn.net/m0_70541367/article/details/132719025
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!