( 取棋子 ) 设有N颗棋子,由人和计算机轮流从中取走若干颗。每方每次最
多取K颗,最少取1颗 (K值不能超过总数的一半,也不能小于1)。试编写一程
序使计算机有较多的获胜机会。
屏幕输入提示:
(1) 输入竞赛规则:A. 取最后一颗棋子的那一方为败.
B. 取最后一颗棋子的那一方为胜.
(2) 总共有多少颗棋子?
(3) 一次最多取几颗?
(4) 谁先取?
(5) 每个回合都应显示: A. 你取几颗?
B. 我取走......颗,还剩......颗.
(6) 竞赛过程中发生违例时,打印出: 竞赛无法进行下去!
(7) 竞赛结束后打印:
I win!(我胜!)或 You win!(你胜!)。
/**************************************************
文 件 名: xiaoyouxi.cpp
文件描述: 构建一个抓球小游戏
创 建 人: 刘基伟
创建日期: 2007年 4月 20日
版 本 号: 1.0
修改纪录:
*************************************************/
#include <stdio.h>
#include <stdlib.h>
#define ZERO 0
#define ONE 1
#define TWO 2
#define FOUR 4
/*=======================================================
函 数 名: My_choise()
参 数: nNum, nMe_max, nMy_select
功能描述: 我选择拿球的数目
返 回 值: int
抛出异常: 无
作 者: 刘基伟 2007/4/20
=======================================================*/
int My_choise(int &nNum,const int nMe_max, int nMy_select);
/*=======================================================
函 数 名: *pMy_choise()
参 数: Num, Me_max, nMy_select
功能描述: 使用指针函数增强函数效率
返 回 值: int
抛出异常: 无
作 者: 刘基伟 2007/4/20
=======================================================*/
int (*pMy_choise)(int &Num,const int Me_max,int nMy_select);
/*=======================================================
函 数 名: Init_ball()
参 数: nBall_number
功能描述: 初始化球
返 回 值: int
抛出异常: 无
作 者: 刘基伟 2007/4/20
=======================================================*/
inline int Init_ball(int &nBall_number);
/*=======================================================
函 数 名: First_select()
参 数: bMe_select, nBall_number, nMe_max, nYou_max
功能描述: 第一次选择
返 回 值: void
抛出异常: 无
作 者: 刘基伟 2007/4/20
=======================================================*/
void First_select(bool &, int &, int &, int &);
/*=======================================================
函 数 名: Select()
参 数: bMe_select, nBall_number, nMe_max,
nYou_max, nSum_num, nMy_select
功能描述: 进入循环体,直到球抓完为止
返 回 值: void
抛出异常: 无
作 者: 刘基伟 2007/4/20
=======================================================*/
void Select(bool , int , int , int , int , int );
int main()
{
bool bMe_select; // 时候轮到我拿球
int nBall_number; // 球的总数
int nMe_max; // 我可以选择的最大数目
int nYou_max; // 你可以选择的最大数目
int nSum_num; // 拿完后球剩的数目
static int nMy_select; // 我拿球的数目
//初始化球
nSum_num = Init_ball(nBall_number);
//第一次选择
First_select(bMe_select, nBall_number, nMe_max, nYou_max);
//进入一个循环体
//两个轮流来拿球
//拿到球没有为止
Select(bMe_select, nBall_number, nMe_max, nYou_max, nSum_num, nMy_select);
return 0;
}
int My_choise(int &nNum,const int nMe_max, int nMy_select)
{
if((ZERO != nNum%TWO) || (ONE == nMe_max)) //剩下的球是奇数,拿一个肯定赢!
{
printf(" 我拿了1个!/n");
nNum--;
for(int i = ZERO; i < nNum; i++)
printf("*");
printf("/n");
return 1;
}
else
{
if((0 != nNum/TWO%TWO) || (TWO == nMe_max)) //如果是偶数,进行除2
{ //得到的结果如果是奇数
printf(" 我拿了2个!/n"); //就拿两个肯定赢
nNum -= TWO;
for(int i = ZERO; i < nNum; i++)
printf("*");
printf("/n");
return TWO;
}
else //以可以拿的最大致
{
for(nMy_select = FOUR; nMy_select < nMe_max; nMy_select+=nMy_select)
if(ZERO != nNum/nMy_select%2)
break;
if(nMy_select == nMe_max)
nMy_select = FOUR;
nNum -= nMy_select;
printf(" 我拿了%d个!/n",nMy_select);
for(int i = ZERO; i < nNum; i++)
printf("*");
printf("/n");
return nMy_select;
}
}
}
int Init_ball(int &nBall_number)
{
int _nBall_number;
printf(" 请输入总数!/n");
scanf("%d",&_nBall_number);
nBall_number = _nBall_number;
return _nBall_number;
}
void First_select(bool &bMe_select, int &nBall_number, int &nMe_max, int &nYou_max)
{
bool _bMe_select;
printf(" 请选择谁先走!0是你,剩下都是我!/n");
scanf("%d",&_bMe_select);
bMe_select = _bMe_select;
for(int nCircle = 0; nCircle < nBall_number; nCircle++)
printf("*");
printf("/n");
nMe_max = nBall_number;
nYou_max = nBall_number;
}
void Select(bool bMe_select, int nBall_number, int nMe_max,
int nYou_max, int nSum_num, int nMy_select)
{
int nCircle; // 循环计数
while(true)
{
if(bMe_select) // 轮到我选择了!
{
if(TWO < nBall_number)
{
pMy_choise = My_choise;
nYou_max = (*pMy_choise)(nBall_number,nMe_max, nMy_select);
}
else if(TWO == nBall_number)
{
if(TWO == nYou_max) // 可以全拿!
nBall_number -= TWO;
else
nBall_number -= ONE;
}
else if(ONE == nBall_number)
{
nBall_number--;
}
else if(ZERO == nBall_number) // 结束 !
{
printf(" 你拿到了最后一个!/n");
printf(" 行!算你赢了!/n");
exit(ZERO);
}
bMe_select = false;
}
else // 轮到你选择了!
{
if(ZERO != nBall_number)
{
int nYou_select; // 你拿球的数目
printf(" 请输入你要拿的数目!/n");
scanf("%d",&nYou_select);
if((nYou_select > nYou_max) || (nYou_select <= ZERO))
{
if(nYou_select == nSum_num)
{
printf(" 不好意思,不可以一次都拿走 !/n");
}
else if(nYou_select <= ZERO)
{
printf(" 不好意思你不可以这么拿,请重新拿 ! /n");
}
else
{
printf(" 不好意思你拿的数目超了,请重新拿 ! /n ");
}
bMe_select = false;
continue;
}
for(nCircle = ZERO; nCircle < nBall_number; nCircle++)
printf("*");
printf("/n");
printf(" 你拿了%d个/n",nYou_select);
nBall_number -= nYou_select;
nMe_max = nYou_select;
for(nCircle = ZERO; nCircle < nBall_number; nCircle++)
printf("*");
printf("/n");
}
else // 结束 !
{
printf(" 我拿到了最后一个!/n");
printf(" 不好意思!我赢了!/n");
exit(ZERO);
}
bMe_select = true;
}
}
}