这个游戏要想赢,只能借助对手失误。如果双方都没有失误,必定是平局。分出了胜负时,仔细分析一下就知道输者有失误。
要是进行人机对战,只要电脑程序设计得好,那将是不可战胜的,最多打个平手。
按你问题补充中的说法,你是想前三步都走角吧,如果你按这种方法跟我玩,前两步走角我拦不住你,但我可以让你第三步不能走角。如果你在第三步硬是要走角,那么你肯定会输给我的。
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 用二维数组编程 井字棋问题求助!、有谁知道张道陵天师所说的过三关,是指哪三关怎么过等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)