井字过三关

井字过三关,第1张

这个游戏要想赢,只能借助对手失误。如果双方都没有失误,必定是平局。分出了胜负时,仔细分析一下就知道输者有失误。

要是进行人机对战,只要电脑程序设计得好,那将是不可战胜的,最多打个平手。

按你问题补充中的说法,你是想前三步都走角吧,如果你按这种方法跟我玩,前两步走角我拦不住你,但我可以让你第三步不能走角。如果你在第三步硬是要走角,那么你肯定会输给我的。

int a[][]=new int[3][3];

for (int i = 0; i < alength; i++) {

for (int j = 0; j < alength; j++) {

a[i][j]=(int)(Mathrandom()2);

}

}

int x=0;

for (int i = 0; i < alength; i++) {

for (int j = 0; j < alength; j++) {

x++;

Systemoutprint(a[i][j]+" ");

if(x%3==0)

Systemoutprintln();

}

}

判断的话if(a[0][0]==a[0][2]==a[0][1])等等都写上就行了

伯阳的基本原理是:主要掌握《易》的乾、坤、坎、离四卦。乾坤象征天地,乾在外坤在内;坎离象征阴阳二气,上下沉浮。日月运转如风箱一样一呼一吸,一进一退,一来一往,均匀而有节律。阴阳相互作用,便产生万物和人。其中乾道成男,坤道成女。人的生命,就是天地阴阳运动在人体内的再现。

魏伯阳内丹的基本程序,有四个阶段和四层境界:第一阶段是筑基,筑基是对人身体机能进行修复、补益,达到精足、气满、神旺的三全境界,这就是“内以养己,安静虚无”道“黄中渐通理,润泽达肌肤”。

第二阶段是炼精化气。这叫小周天功法。就是以意领气运行体内:“知白守黑,神明自来”。气由会阴穴沿督脉上行,过三关(尾闾、夹脊、玉枕)到泥丸(脑神),称“河车搬运”。再沿任脉下行入丹田,这叫小周天。其作用是:“阴阳互会”“真人至妙”。

第三阶段是炼气化神。这叫大周天功法。主要是内视元气弥漫于中丹田,下丹田之间,由微动到不动,最后尽化,所以叫“十月养胎”。用入定之功,使人的“元神”发育成长,就像母体怀胎儿一样。这是炼性。可以返老还童,延年益寿。

第四阶段是炼神还虚。这是最高境界。它要求:“耳目口三室,闭塞勿发通,真人潜深渊,浮游守规中。”结果是:“颜容浸以润,骨节益坚强,排除众阴邪,然后立正阳。”“**若春泽,液液象解冰,从头流至足,究竟复上升。”这就达到“累积长久,化形成仙”“百世以下,遨游人间”的长生久视的养生目标了。

错误集中在下面这段语句,即输入下棋位置的合理性判断。

do

{

printf("Player %d,please enter where you want to put your %c:",player,(player==1)'x':'o');

scanf("%d",&choice);

row=--choice/3;

column=--choice%3; // 第一处错误

}while(i<1||i>9||board[row][column]>'9'); // 第二处错误

第一处错误是:column=--choice%3;

原因:--运算符没搞清楚。--运算符意思是先减一,再做别的运算。那么,这句话就相当于 choice -= 1; coloumn = choice%3; 这样就看出来, choice -= 1;这半句话是多余的,只要出现在 row=--choice/3;这里就足够了。

因为这里多运算了一次choice-1,所以输入1的时候行运算正确而列运算少了1,要么触碰边界,要么遇到了其他格子。

由于--运算符很容易出错,所以一般谨慎的程序员很少用,转而用复杂的语句代替,至少意思比较明白。

第二处错误是: i<1||i>9

原因:i 这里应该是棋手的落子顺序。第一手是0,判断为棋手1。但是用在这个语句里明显出错。这个语句应当是判断棋手落子的位置,即是不是下在棋盘外面,所以应当是choice<1 || choice>9,然而结合第一处错误,仍然是错的,因为choice已经在计算row 和column的时候被改变了。

因为这处错误,第一手棋永远无法走完,因为i初始值为0,满足i<1这个条件,进而出现死循环

结合两处错误,建议这样改:

do

{

printf("Player %d,please enter where you want to put your %c:",player,(player==1)'x':'o');

scanf("%d",&choice);

row=(choice-1)/3; // 修改

column=(choice-1)%3; // 修改

}while(choice<1||choice>9||board[row][column]>'9'); // 修改

给你一份详细的代码吧,

已经编译运行确认了:

#include <iostream>

#include <string>

using namespace std;

typedef char chess[10]; //字符数组

typedef int temparr[10]; //整型数组

chess arr; //定义字符数组变量

temparr brr; //定义整型数组变量

int number,suc,n3,c3,n2,c2,n1,c1;

void inarrdata(chess a) //初始化棋盘编号

{

a[1]='1';a[2]='2';a[3]='3';

a[4]='4';a[5]='5';a[6]='6';

a[7]='7';a[8]='8';a[9]='9';

}

void display(chess a) //输出棋盘状态

{

cout<<endl;cout<<endl;

cout<<" "<<a[1]<<" "<<'|'<<" "<<a[2]<<" "<<'|'<<" "<<a[3]<<endl;

cout<<" -----------"<<endl;

cout<<" "<<a[4]<<" "<<'|'<<" "<<a[5]<<" "<<'|'<<" "<<a[6]<<endl;

cout<<" -----------"<<endl;

cout<<" "<<a[7]<<" "<<'|'<<" "<<a[8]<<" "<<'|'<<" "<<a[9]<<endl;

cout<<endl;cout<<endl;

}

int arrfull() //判断还有没有下棋的位置

{

int i;

int arrf=0;

for(i=1;i<=9;i++)

if(i==arr[i]-48) //如果字符arr[i]-48等于i

arrf=1; //那么arrf=1,也就是可以走棋

return arrf;

}

void cn(int line) //判断状态

{

switch(line)

{

case 0:c3=c3+1;break;

case 1:n2=n2+1;break;

case 2:c2=c2+1;break;

case 3:n1=n1+1;break;

case 4:c1=c1+1;break;

case 5:n3=n3+1;break;

}

}

int linenum(char a,char b,char c) //判断状态

{

int ln=6;

if((a=='X')&&(b=='X')&&(c=='X'))

ln=0;

if(((a=='O')&&(b=='O')&&(c!='O'))||((a=='O')&&(b!='O')&&(c=='O'))||((a!='O')&&(b=='O')&&(c=='O')))

ln=1;

if(((a=='X')&&(b=='X')&&(c!='X'))||((a=='X')&&(b!='X')&&(c=='X'))||((a!='X')&&(b=='X')&&(c=='X')))

ln=2;

if(((a=='O')&&(b!='O')&&(c!='O'))||((a!='O')&&(b=='O')&&(c!='O'))||((a!='O')&&(b!='O')&&(c=='O')))

ln=3;

if(((a=='X')&&(b!='X')&&(c!='x'))||((a!='X')&&(b=='X')&&(c!='X'))||((a!='X')&&(b!='X')&&(c=='X')))

ln=4;

if((a=='O')&&(b=='O')&&(c=='O'))

ln=5;

return ln;

}

int maxbrr(int br) //判断最大权值

{

int temp,i,mb;

temp=-888;

for(i=1;i<=9;i++)

{

if(temp<=br[i])

{

temp=br[i];

mb=i;

}

}

return mb;

}

void manstep() //人走棋处理模块

{

int j;

display(arr);

if(arrfull()) //如果棋盘上还有下棋的位置,人走一步棋

{

cout<<"您要走哪一步?请输入数字(1--9):";

cin>>j;

while((j<1)||(j>9)||(j!=arr[j]-48))

{

cout<<"对不起,您输入的数字不对,请重新输入(1--9):";

cin>>j;

}

arr[j]='O';

n3=0;c3=0;n2=0;c2=0;n1=0;c1=0;

number=linenum(arr[1],arr[2],arr[3]);cn(number);

number=linenum(arr[4],arr[5],arr[6]);cn(number);

number=linenum(arr[7],arr[8],arr[9]);cn(number);

number=linenum(arr[1],arr[4],arr[7]);cn(number);

number=linenum(arr[2],arr[5],arr[8]);cn(number);

number=linenum(arr[3],arr[6],arr[9]);cn(number);

number=linenum(arr[1],arr[5],arr[9]);cn(number);

number=linenum(arr[3],arr[5],arr[7]);cn(number);

if(n3!=0) //您赢了

{

display(arr);

cout<<endl;

cout<<"恭喜您赢了!!!"<<endl;

suc=0;

}

}

}

void computerstep() //计算机走棋处理模块

{

int i;

if(arrfull()) //如果棋盘上还有可下棋的位置,则计算机走棋

{

for(i=1;i<=9;i++) //对每一步可走的棋进行计算

{

if(i==arr[i]-48)

{

c3=0;n2=0;c2=0;n1=0;c1=0;

arr[i]='X';

number=linenum(arr[1],arr[2],arr[3]);cn(number);

number=linenum(arr[4],arr[5],arr[6]);cn(number);

number=linenum(arr[7],arr[8],arr[9]);cn(number);

number=linenum(arr[1],arr[4],arr[7]);cn(number);

number=linenum(arr[2],arr[5],arr[8]);cn(number);

number=linenum(arr[3],arr[6],arr[9]);cn(number);

number=linenum(arr[1],arr[5],arr[9]);cn(number);

number=linenum(arr[3],arr[5],arr[7]);cn(number);

brr[i]=(128c3-63n2+31c2-15n1+7c1); //计算此步权值

arr[i]=i+48;

}

else

brr[i]=-999;

}

arr[maxbrr(brr)]='X'; //确定计算机走哪一步,权值最大的一步

c3=0;n2=0;c2=0;n1=0;c1=0;

number=linenum(arr[1],arr[2],arr[3]);cn(number);

number=linenum(arr[4],arr[5],arr[6]);cn(number);

number=linenum(arr[7],arr[8],arr[9]);cn(number);

number=linenum(arr[1],arr[4],arr[7]);cn(number);

number=linenum(arr[2],arr[5],arr[8]);cn(number);

number=linenum(arr[3],arr[6],arr[9]);cn(number);

number=linenum(arr[1],arr[5],arr[9]);cn(number);

number=linenum(arr[3],arr[5],arr[7]);cn(number);

if(c3!=0) //计算机已赢

{

display(arr);

cout<<endl;

cout<<"计算机赢了!!!"<<endl;

suc=0;

}

}

else

suc=0;

}

int main()

{

cout<<"游戏规则:"<<endl<<"棋盘格式如图,人和计算机在棋盘上交替走棋"<<endl;

cout<<"约定计算机使用符号X,人使用符号O"<<endl;

cout<<"谁先使一横行或一竖行或对角线上有三个自己的符号,就胜利了!"<<endl;

string s="y";

string ch;

while(s=="y"||s=="Y")

{

inarrdata(arr); //棋盘坐标编号

display(arr); //显示初始棋盘

suc=1;

cout<<"请选择您是否先走(y/n)";

cin>>ch;

while(ch!="y"&&ch!="Y"&&ch!="n"&&ch!="N")

{

cout<<"错误!请输入y或n:";

cin>>ch;

}

if((ch=="y")||(ch=="Y")) //输入Y,表示人先走棋

{

while(suc)

{

manstep();

computerstep();

}

}

else //计算机先走棋

{

while(suc)

{

computerstep();

if(suc)

manstep();

}

}

if(n3==0&&c3==0)

cout<<endl<<"和棋!"<<endl<<endl;

cout<<"再来一盘(y/n)";

cin>>s;

while(s!="y"&&s!="Y"&&s!="n"&&s!="N")

{

cout<<"错误!请输入y或n:";

cin>>s;

}

}

return 0;

}

井字棋可能是最简单的棋类游戏了,它简单到了成年人之间玩几乎总是平局的地步。因此,这个游戏貌似最多只能哄哄小孩子。不过,对井字棋游戏中所有可能的情况进行一番细致的分析,你会发现一个你或许不会料到的惊人结论——先手的最优策略不是稳坐正中央,而是先占一个角! 几年前,曾经自己动手写过一个和人下井字棋的电脑程序,运行之后却发现电脑先走时总爱把第一步棋下在角上;检查程序代码许久后才意识到,电脑程序可能并没有问题。人们往往有一个定势思维,认为由于从正中央出发能够得到的连线最多,因此最优策略必然是先占住正中央这块宝地。然而,经验是一回事,实际上就是另一回事了——这个电脑程序看似很没头脑地往角里下棋,但几乎总是在赢。 无独有偶,国外著名的 Geek 漫画 xkcd 最近画了一幅井字棋最优策略完全图,同样给出了这个违反直觉的结论:第一步走在角上才是最佳的策略。 这究竟是为什么呢?不妨让我们看一看,如果第一步真的走角,会发生哪些情况。 先手先占角! 游戏开始后,二话不说先占上一个角(比如左下角吧),那么对方总共有五种本质不同的应对策略:占据靠近你的那条边,占据靠近你的那个角,占据远离你的那条边,占据远离你的那个角(即对角),以及占据正中央的位置。不可思议的是,在这五种策略中,前面四种都是陷阱——如果对方不慎选择了前面四种策略中的任意一种,他就必然输掉。 上图显示了在这四种情况下你可以如何把对方一步步逼上绝路。假设对方走正下方,占据了一个靠近你的边(最左边的那个图),你就可以占据正中央来应对,逼迫对方不得不走右上角。这时,只需要在左上角放下一子,你就赢定了——图中出现了两条只差一子的连线,对方不可能兼顾得了。 右边几个图显示了对方第一步棋的其它几种走法。选择合适的位置应对他,都可以在下一步迫使对方只剩一种走法,接下来你便可以下出“一箭双雕”的棋,让对方无法彻底封杀你。 也就是说,当你占据棋盘一角后,在对方下一步棋的八个可选位置中,其中七个位置都是必输的,陷阱摆满了几乎整个棋盘。在面对“先走一角”的诡异开局时,你的朋友说不准就会慌了手脚,没能冷静地占住中间,决定了必败的命运。 对方要是真的走了正中间,你仍然有赢的机会。你可以占住右上角的位置(如上图)。如果对方不幸走了剩下的两个角中的一个(上图左),你便能故技重施,再次取得胜利。只有对方选择了边上的位置(上图右),才能躲过这一系列的陷阱,最终变成平局。 难怪计算机会把角上的位置当作宝地呢。 后手还是先占角! 作为后行者,你遇到的往往是“先走中间”的经典开局。此时,千万别忘了,先占角仍然是一条金科玉律。如果你不慎走了某条边的位置,对方可就赢定了!对方可以向上面的第一幅图那样,在正右方下子应对,逼迫你把下一步棋落在正左方。此时,对方便可占据右上方的位置,同时产生出两条仅差一子的连线。右边三幅图则显示,如果你在角上应对,最终总会是一盘和棋。

以上就是关于井字过三关全部的内容,包括:井字过三关、Java 用二维数组编程 井字棋问题求助!、有谁知道张道陵天师所说的过三关,是指哪三关怎么过等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9465433.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存