推荐阅读:
超级详细的注释C语言简单实现童年小游戏:贪吃蛇_有·意思的博客-CSDN博客
三子棋游戏规则
:
是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、三字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。
主要思路
:
从规则上可以把三字棋看成是一个3×3的矩阵,只要行、列或对角线上形成三个相同的图案判断为胜利。所以我可以把三子棋的棋盘看成是一个三行三列的数组,去判断数组元素的异同根据三子棋胜利规则判断胜利,当然这里主要实现的是人机交互的三子棋(玩家与玩家的三子棋只需要做一些小的改动即可)
人机交互的话,游戏的实现就需要玩家下棋步骤与电脑自动下棋步骤,可以分别用两个函数实现。这里主要只写了电脑走的函数void diannao(char str[row][col],int x,int y)实现电脑走,玩家下棋部分包含在了函数void game_sanzi()中。
电脑走函数:
//定义char str二维数组形参,row col为数组行列包含在头文件game_san.h
//x,y为了传递行数和列数这里我觉得有单多余但是懒得修改了
void diannao(char str[row][col],int x,int y)
{
system("cls");//清屏函数
printf("电脑走->:\n");
while (1)//设置死循环直到电脑随机产生的坐标可以落子退出
{
int m = rand() % x;
int n = rand() % y;
if (str[m][n] == ' ')//判断是否为空格若是可以落棋
{
str[m][n] = '#';//‘#’代表电脑棋子
break;//下完棋退出这个随机循环
}
else if (str[m][n] == '*')continue;//判断如果次坐标有玩家棋子不能落子再次循环
}
}
控制游戏进行game_sanzi()函数:
void game_sanzi()
{
int z;
int s;
int count=0;
char str[row][col];//定义一个二维数组
for(int i=0;i<row;i++)//用空格初始化数组
for (int x = 0; x < col; x++)
{
str[i][x] = ' ';
}
while (1)//死循环重复下棋直到胜利退出
{
print(str, row, col);//自定义显示三子棋棋盘与棋子函数
printf("玩家走->(坐标输入例如:11或者12) : ");//玩家输入坐标为十进制两位数
scanf("%d", &z);
if ((z >= 31 && z <= 33) || (z >= 21 && z <= 23) || (z >= 11 && z <= 13))
{
//条件限制玩家输入的坐标能对应棋盘的数组坐标
count = 0;//计数器归零
str[(z / 10) - 1][(z % 10) - 1] = '*';//玩家棋子‘*’落子
print(str, row, col);//输出显示当前棋子棋盘
s=win_(is_win(str, row, col));//判断是否胜利
if (s == 1)break;//玩家胜利退出循环
diannao(str,3,3);//电脑下棋
print(str, row, col);//
system("cls");//清屏这里有点问题,可以去掉这里放在上一行
s=win_(is_win(str, row, col));//判断是否有胜利方
if (s == 0)break;//电脑胜利退出循环
//if((str[1][1]==str[12]==str[13])||(str[1][1]==str[2][2]==str[3][3]=='*')||(str[]))
continue;//否则继续下棋
}
else//若玩家输入坐标超过三次失误退出游戏
{
printf("请重新输入有效坐标你还有%d次机会否则退出\n",(3-count));
count++;
if (count == 3)exit(0);
continue;
}
}
}
棋盘显示函数:
void print(char (*str)[3],int x,int y)
{
for(int i=0;i<x;i++)//控制行
for (int m = 0; m < y; m++)//控制列
{
if (m >= 0 && m <= 1)//若列数在0,1则输出竖线控制棋盘格式
{
printf("%c |", str[i][m]);
}
else
printf("%c", str[i][m]);
if (m == 2)
{
printf("\n");
printf("-- -- --\n");//控制棋盘横线格式
}
}
}
判断输赢:
//这里主要是写在头文件“game_san.h”中
//所以要用这里面的函数的话需要引用头文件
#pragma once
#include"game_san.h"
char is_win(char str[][3],int m,int y)
{
int count1=0;
for (int i = 0; i < row; i++)//判断每行是否有相同的‘*’或则‘#’
{
if (str[i][0] != ' ' && str[i][1] == str[i][2] && str[i][0] == str[i][1])
{
return str[i][0];
}
}
for (int i = 0; i < col; i++)//判断每列是否有相同的‘*’或则‘#’
{
if (str[0][i] != ' ' && str[1][i] == str[2][i] && str[0][i] == str[1][i])
{
return str[0][i];
}
}
//对角线上判断是否相同
if ((str[0][0] != ' ' && str[1][1] == str[2][2] && str[1][1] == str[0][0]) || (str[1][1] != ' ' && str[1][1] == str[2][0] && str[0][2] == str[1][1]))
{
return str[1][1];
}
}
//判断是那一方胜利并且返回0,1结束循环并打印
int win_(char x)//这个函数有点多余主要是我的代码不够精简
{
if (x == '*')
{
printf("玩家获胜!!!\n"); return 1;
}
else if (x == '#')
{
printf("电脑获胜!!!\n"); return 0;
}
}
主要函数代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include"game_san.h"
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include"is_win.h"
void menu(int *x)
{
printf("***************************\n");
printf("****** 1--开始游戏 *******\n");
printf("*******2--退出游戏*********\n");
printf("***************************\n");
scanf("%d",x);
}
void print(char (*str)[3],int x,int y)
{
for(int i=0;i<x;i++)
for (int m = 0; m < y; m++)
{
if (m >= 0 && m <= 1)
{
printf("%c |", str[i][m]);
}
else
printf("%c", str[i][m]);
if (m == 2)
{
printf("\n");
printf("-- -- --\n");
}
}
}
void diannao(char str[row][col],int x,int y)
{
system("cls");
printf("电脑走->:\n");
while (1)
{
int m = rand() % x;
int n = rand() % y;
if (str[m][n] == ' ')
{
str[m][n] = '#';
break;
}
else if (str[m][n] == '*')continue;
}
}
void game_sanzi()
{
int z;
int s;
int count=0;
char str[row][col];
for(int i=0;i<row;i++)
for (int x = 0; x < col; x++)
{
str[i][x] = ' ';
}
while (1)
{
print(str, row, col);
printf("玩家走->(坐标输入例如:11或者12) : ");
scanf("%d", &z);
if ((z >= 31 && z <= 33) || (z >= 21 && z <= 23) || (z >= 11 && z <= 13))
{
count = 0;
str[(z / 10) - 1][(z % 10) - 1] = '*';
print(str, row, col);
s=win_(is_win(str, row, col));
if (s == 1)break;
diannao(str,3,3);
print(str, row, col);
system("cls");
s=win_(is_win(str, row, col));
if (s == 0)break;
//if((str[1][1]==str[12]==str[13])||(str[1][1]==str[2][2]==str[3][3]=='*')||(str[]))
continue;
}
else
{
printf("请重新输入有效坐标你还有%d次机会否则退出\n",(3-count));
count++;
if (count == 3)exit(0);
continue;
}
}
}
int main()
{
srand((unsigned int)time(NULL));
int x;
menu(&x);
while (1)
{
switch (x)
{
case 1:game_sanzi(); break;
case 2:exit(0); break;
default:printf("请重新输入:\n"); break;
}
}
return 0;
}
弊端
:这个代码还不够精简,有些步骤可以简化并且此代码没有考虑到如何实现电脑和玩家平局的局面,可以后期修改,码字不易,多多鼓励。不足之处还希望指出,谢谢。
补充
:game_san.h头文件中只包括:
#define row 3
#define col 3