C语言实现三子棋游戏(意义版)

   

我还会再遇到ta。

所以,这并不算是真正意义上得离别。

虽然从近几个月几乎每天都跟ta走的颇近。每次得相遇都会让我恍惚。

我想躲着ta的一些,但是每次提起思绪却总会跟ta不期而遇。

遇时苦恼,别时着迷。

昨日又与ta相遇,这一聚,就是六个多时辰。从正午窗外得鸣笛到回头时到卷闸门刺耳的伸展,我才想起跟一碗炸酱面不见不散得约定。

跟后者比起来,离别带给我的,更是精神食粮。


好了ta就是BUG

实现了三子棋后,这一离别才显得更有意义。理解和实现差之千里,编程就是这样。对于实现入门三子棋可能是大同小异的,但是我在内部加入了标签,让这个小程序变得更加意义深刻,同时一记与BUG的不解之缘。

实现:

首先应该想到使用函数来使分工简洁明确

菜单,游戏功能。

菜单:    

main函数中设定menu()函数来打印菜单 即 开始游戏和退出游戏,使用do while语句来调用游戏功能game()函数。实现完整的互动。


对于游戏内部功能game()而言,设置 

1 初始化棋盘 (空格和外观)打印棋盘 (每次下棋后进行结果显示)3 用户下棋   4  电脑随机下棋 

输赢判断 6 平局判断

这么多函数都放在一个源文件显然是酸辣的,所以我们定义一个实现游戏的头文件”threechess.h“进行函数的声明,后编写定义他们的源文件”threechess.c".

第一步:先在main函数中讲函数流程实现

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include"threechess.h"
#include<Windows.h>
#include<time.h>
void menu()
{
	printf("*******************************************\n");
	printf("------ 我可以大口吞下玻璃而不伤身体--------\n");  //label 1. original test.
	printf("------1.  开始游戏-------------------------\n");
	printf("------0.  退出游戏-------------------------\n");
	printf("*******************************************\n");

};void game();
int main()
{
	menu();
	int a = 0;

	do
	{
		assert(scanf("%d", &a));//防止用户输入非整型十进制数字
		switch (a)
		{
		case 1:
			game();
			menu();
			break;
		case 0:
			return 0;
                default: printf("输入错误");
		}
	} while (a);
}

threechess.h

第二步 编写游戏功能的头文件

#pragma once
#define ROW 3
#define COL 3


void	initboard(char arr[ROW][COL], int row, int col);//初始化棋盘
//打印棋盘
void    display(char arr[ROW][COL], int row, int col);
//人走棋
void playermove(char arr[ROW][COL], int row, int col);
//机器走
void automove(char arr[ROW][COL], int row, int col);
//判断输赢
int JUDGE(char arr[ROW][COL], int row, int col);
//平局情况
int FULL(char arr[ROW][COL], int row, int col);
threechess.c

第三步在该源文件中定义功能

#include "threechess.h"
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void initboard(char arr[ROW][COL], int row, int col)//此处第一个参数是指产生二维指针,不能够省略第一个下标符第二个下标符和值
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = ' ';  //将内容初始化
		}
	}
}
void display(char arr[ROW][COL], int row, int col)//显示棋盘
{
	int i = 0;
	int j = 0;
	printf("-------------\n");
	for (i = 0; i < row; i++)
	{
		printf("|");
		for (j = 0; j < col; j++)
		{
			printf(" %-2c|", arr[i][j]);
		}
		if (row - 2 == i)
		{
			(printf("        ***帮帮乌干达得可怜儿童!***"));    // label 2.VIM version 
		}
		printf("\n-------------\n");// 目的在于每行打印完了以后再下面加上栅;
	}
}
void playermove(char arr[ROW][COL], int row, int  col) //玩家移动
{
	while (1)
	{
		int x = 0, y = 0;
		assert(scanf("%d%d", &x, &y));//此处强调,如果用用户输入的值非十进制整型,比如%……&*&*!@#asdvc字符型,那么scanf函数将不进行匹配,返回匹配成功的项目数,用assert断言函数来进行判断
		x--;//因为用户输入得值位数组下表加一所以在这里--
		y--;
		if ((x >= 0 && x < row) && (y >= 0 && y < col))//防止越界
		{
			if (' ' == arr[x][y])
			{
				arr[x][y] = '*';
				break;
			}
			else
			{
				printf("\n此位置已放置\n");
			}
		}
		else
		{
			printf("\n你飘了\n");  //没放好就是飘了
		}
	}
}

void automove(char arr[ROW][COL], int row, int col)//电脑移动
{
	srand((unsigned)time(NULL));  //设置随机起点

	while (1)
	{
		int x = rand() % 3;   //使随机值在0-2
		int y = rand() % 3;
		if (' ' == arr[x][y])  //防止重叠
		{
			arr[x][y] = 'X';
			break;
		}
	}
}
int JUDGE(char arr[ROW][COL], int row, int col)  //判断
{
	int i = 0;
	for (i = 0; i < ROW; i++)//判断列
	{
		if (arr[i][COL - 1] == arr[i][COL - 2] && arr[i][COL - 2] == arr[i][COL - 3]) //此处当下标时 数值要-1 很关键!
		{
			if (arr[i][COL - 1] != ' ')
			{
				return arr[i][COL - 1];
			}
		}
	}
	for (i = 0; i < COL; i++) //判断行
	{
		if (arr[ROW - 1][i] == arr[ROW - 2][i] && arr[ROW - 2][i] == arr[ROW - 3][i])
		{
			if (arr[ROW - 1][i] != ' ')
			{
				return arr[ROW - 1][i];
			}
		}
	}
	if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2])  //判断斜行
	{
		if (arr[0][0] != ' ')
		{
			return arr[0][0];    //返回复合条件的字符
		}
	}
	if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0])//判断对称斜行
	{
		if (arr[0][2] != ' ')
		{
			return arr[0][2];  //返回复合条件的字符
		}
	}
	if (FULL(arr, row, col) == 0) //在judge中引用FULL函数进行平局判断
	{
		return 'd';//返回复合条件的字符

	}

	return 0;  //没有返回0
}
int FULL(char arr[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 (' ' == arr[i][j])
			{
				return 1; //供judge判断
			}

		}
	}
	return 0;
}


第四步,game()功能实现

void game()
{
	char arr[ROW][COL] = { 0 };
	initboard(arr, ROW, COL);  
	display(arr, ROW, COL);
	
	
		while (1)
		{
			playermove(arr, ROW, COL);  //玩家操作
			display(arr, ROW, COL);//将结果显示
			if (JUDGE(arr, ROW, COL) != 0)//判断是否产生结果
			{
				break;
			}
			automove(arr, ROW, COL);  //电脑操作
			display(arr, ROW, COL);//显示结果
			if (JUDGE(arr, ROW, COL) != 0)//判断
			{
				break;
			}
			
			
		}
		if (JUDGE(arr, ROW, COL) =='d' )//结束后检测是否复合平局判断
		{
			printf("你勉强合格");//输出平局结果
		}
		else if (JUDGE(arr, ROW, COL) == 'X')//电脑胜出结果判断
		{
			printf("出门左转上336\n");
		}
		else if (JUDGE(arr, ROW, COL) == '*')//玩家结果判断
		{
			printf("THAT'S VERY KIND OF YOU!\n");
		}

	return 0;}                                    
 

输出结果

1.界面


1.电脑赢


2.玩家赢


**对于label 1与2 

1.来字linux系统经典字体测试

2.来自vim的欢迎语

显得更有意义。

**关于scanf的返回值,scanf返回的是正确入读的项目数,即(%d%d%d,&a,&b)它的返回值也是3,但是如果第一个项目未提取成功,那么即使后面是正确的类型,返回值也是0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值