C语言实现Nim游戏

Nim概述

nim游戏详解(易懂)

再强调一遍结论:
对于一个Nim游戏的局面(a1,a2,…,an),它是P-position当且仅当a1^ a2^ … ^ an=0,其中“^”指抑或(xor)运算。
这便是整个程序的基础。

话不多说,直接上代码:

代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>

int main() {
	// 变量定义及随机数种子的创建
	const short max = 50;
	short k, j, m, a, d, turn;
	short i, sum, or_, dif, n_, beg, re;
	short n[9] = { 0 };
	time_t ts;
	unsigned int t = time(&ts);
	sum = 0, beg = 1;
	srand(t);
	// 简介及设置
	puts(" Welcome to NIM:\n \n (作者筱霖恋,欢迎交流学习)\n 现有k(1<=k<=9)堆石子,");
	puts(" 每堆所包含的石子数{n1,n2,...nk}均为50以内的随机正整数。\n 玩家与NPC进行游戏,");
	puts(" 双方轮流从任选的第j堆中拿去m(1<=m<=a,1<a<=50)个石子,\n 拿完最后一个石子者获胜 >_<\n");
	while (1) {
		putchar(' ');
		for (i = 0; i < 60; i++) {
			putchar('-');
		}

		printf("\n 请输入难度d(0<=d<=5):\n d:");
	A1:scanf_s("%hd", &d);
		if (d < 0 || d > 5) {
			printf(" 诶呀,粗错了,请重新输入~\n d:");
			goto A1;
		}
		printf
		(" 请分别输入k和a,数额请不要过大,中间用空格连接:\n O0:");
	A2:scanf_s("%hd %hd", &k, &a);
		if (a > 1 && a < max && k >= 1 && k <= 9) {
			for (i = 0; i < k; i++) {
				n[i] = rand() % (max - a) + (a + 1);
				sum += n[i];
			}
		}
		else if (a == max && k >= 1 && k <= 9) {
			for (i = 0; i < k; i++) {
				n[i] = max;
				sum += n[i];
			}
		}
		else if (a <= 1 || a > max || k < 1 || k > 9) {
			printf(" 诶呀,粗错了,请重新输入~\n O0:");
			goto A2;
		}
		while (sum) {
			if (beg == 0)
				printf("\n C :");
			else
				printf(" P :");
			// 玩家局面
			for (i = 0; i < k; i++) {
				printf("%2d ", n[i]);
			}
			if (beg) {
				if (beg == 1) {
					printf
					("\n 请决定先后手,若您先手,请输入1,否则,请输入0:\n turn:");
				A3:scanf_s("%hd", &turn);
					if (turn == 0) {
						beg = 2;
						goto A5;
					}
					else if (turn != 1) {
						printf(" 诶呀,粗错了,请重新输入~\n turn:");
						goto A3;
					}
				}
				puts("\n (以下内容中,O1代表玩家操作,O2代表NPC操作,P代表操作后局面。)");
				printf(" 请分别输入j和m,中间用空格连接(下同):\n ");
				for (i = 0; i < 60; i++) {
					putchar('-');
				}
				beg = 0;
			}
			// 人机交互
			puts("\n ");
			printf(" O1:");
		A4:scanf_s("%hd %hd", &j, &m);
			j--;
			if (m >= 1 && m <= a && j >= 0 && j < k && n[j] >= m) {
				sum -= m;
				if (sum == 0) {
					printf("\n You win!!!\n ");
					putchar('\n ');
					break;
				}
				n[j] -= m;
				printf(" P :");
				for (i = 0; i < k; i++) {
					printf("%2d ", n[i]);
				}
				or_ = n[0] % (a + 1);
				for (i = 1; i < k; i++) {
					or_ = or_ ^ (n[i] % (a + 1));
				}
				// 竞争模式
			A5:if (or_ != 0) {
				or_ = rand() % 5;
				if (or_ >= 0 && or_ < 5 - d) {
					goto A6;
				}
				j = 0;
				for (i = 1; i < k; i++) {
					if (n[j] < n[i]) {
						j = i;
					}
				}
				dif = 0, n_ = n[j];
				while (or_ != 0) {
					n[j]--;
					dif++;
					or_ = n[0] % (a + 1);
					for (i = 1; i < k; i++) {
						or_ = or_ ^ (n[i] % (a + 1));
					}
					if (dif == a + 1 || n[j] == -1) {
						n[j] = n_;
						dif = 0;
						j = (j + 1) % k;
						while (n[j] == 0) {
							j = (j + 1) % k;
						}
						n_ = n[j];
					}
				}
				sum -= dif;
			}
			   // 随机模式
			   else {
			A6:j = rand() % k;
				while (n[j] == 0) {
					j = (j + 1) % k;
				}
				dif = rand() % a + 1;
				while (n[j] < dif) {
					dif--;
				}
				n[j] -= dif;
				sum -= dif;
			}
			   printf("\n O2:%hd %hd", j + 1, dif);
			   if (sum == 0) {
				   printf("\n \n NPC wins!!!\n ");
			   }
			   putchar('\n ');
			}
			else {
				printf(" 诶呀,粗错了,请重新输入~\n O1:\n ");
				goto A4;
			}
		}
		getchar();
		printf("\n 请问您还要继续游戏吗?\n 再来一局请输入0,退出请输入其他任意字符:");
		scanf_s("%hd", &re);
		switch (re)
		{
		case 0:
			putchar('\n');
			continue;
		default:
			exit(0);
		}
	}
	system("pause");
	return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值