圍棋要實現什麼功能呢? 首先是黑棋和白棋,下麵的代碼,黑棋占領的位置被賦值為1,白棋是2; 其次有幾個圍棋中的規則(不知道是不是這樣的,老師是這麼告訴我的,可以指正):1.塊:上下左右可以連起來的叫塊,一顆棋上下左右四個方向若有棋子,就可以稱作是一塊,一個棋子上下左右都沒有,也可以稱作一塊。2.氣: ...
圍棋要實現什麼功能呢?
首先是黑棋和白棋,下麵的代碼,黑棋占領的位置被賦值為1,白棋是2;
其次有幾個圍棋中的規則(不知道是不是這樣的,老師是這麼告訴我的,可以指正):1.塊:上下左右可以連起來的叫塊,一顆棋上下左右四個方向若有棋子,就可以稱作是一塊,一個棋子上下左右都沒有,也可以稱作一塊。2.氣:就是一個塊周圍(上下左右)都沒有棋的地方,那就是氣。
那麼要實現什麼呢?就是每下一次棋,返回一方所有的塊和每一塊有多少氣。如果沒氣了,就把圍住的棋都取走(數組裡就是清為0)。
先來看看主函數
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxsize 10
#define null 0
typedef struct node{
int x;
int y;
struct node*next;
} lqnode;
typedef struct{
node *front,*rear;
}Queue;
//定義了兩個結構體,一個是隊列,一個是節點
int main(){
int chess[10][10];
int savechess[10][10];//設置了一個數組保存之前下個棋盤
int i,j,type=1,a,b,flag=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
chess[i][j]=0;
}
}
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf(" %d",chess[i][j]);
}
printf("\n");
}
printf("黑手:");
//執黑子先手
while(scanf("%d %d",&a,&b)!=EOF){
//輸入一方要下的位置
if(flag==0){
type=1;//黑方是1
flag=1;
}else{
type=2;//白方是2
flag=0;
}
//利用以上實現黑方白方切換
chess[a][b]=type;//下棋
//保存之前的棋盤
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
savechess[i][j]=chess[i][j];
}
}
lumpgas(chess,type);
//把所有七七八八的放在一個函數里,傳入的參數現在的棋盤,以及現在是哪一方下棋,因為傳入的數組會在函數里發生改變,所以上面的savechess就是為了保存。
//賦值,更新現在的棋盤
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(chess[i][j]==9 ||chess[i][j]==6 ||chess[i][j]==3){//為什麼是這個條件,下麵看lumpgas再解釋
chess[i][j]=savechess[i][j];
}
}
}
//輸出下過之後的棋盤
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf(" %d",chess[i][j]);
}
printf("\n");
}
//如果上面是黑棋,那下一個就是白棋下辣!
if(type==1){
printf("白手\n");
}else{
printf("黑手\n");
}
}
return 0;
}
現在就來看看lumpgas函數里實現的功能
void lumpgas(int chess[10][10],int type){
int total=0;//這個是用來標記的,下麵看看怎麼退出迴圈
int twtype=type*3;//這也是用來標記下麵是否迴圈過
while(total==0){//為什麼是迴圈呢,就是說每一方可能不止只有一個塊
Queue *q;
lqnode *p;
q=(Queue *)malloc(sizeof(Queue));
p=(lqnode *)malloc(sizeof(lqnode));
p->next=null;
q->rear=p;
q->front=p;
int x=0,y=0,flag=1;
//下麵就用黑方為例來講解吧,先找到黑方的第一個占領的位置
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(chess[i][j]==type && flag==1){
x=i;
y=j;
flag=0;//因為是二維,所以用這個方法來記錄下標
}
}
}
chess[x][y]=type*3;//用來記錄這個點已經找過了,以便於下一次迴圈找其他的塊
lqnode *r,*t;
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y;
q->rear->next=r;
r->next=null;
q->rear=r;
//進隊列
t=q->front->next;
x=t->x;
y=t->y;
int num=0;
while(num!=4){
num=4;//這個是迴圈的條件,如果說這個節點上下左右都沒有可以進入隊列的節點了就退出
//以下是廣度優先來找連在一起的點,找到就進隊列,上下左右都找
if(chess[x-1][y]==type){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y+1;
q->rear->next=r;
r->next=null;
q->rear=r;
chess[x-1][y]=twtype;//標記一下這個地方已經找過了
num--;
}
if(chess[x+1][y]==type){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x+1;
r->y=y;
q->rear->next=r;
r->next=null;
q->rear=r;
chess[x+1][y]=twtype;
num--;
}
if(chess[x][y-1]==type){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y-1;
q->rear->next=r;
r->next=null;
q->rear=r;
chess[x][y-1]=twtype;
num--;
}
if(chess[x][y+1]==type){
r=(lqnode *)malloc(sizeof(lqnode));
r->x=x;
r->y=y+1;
q->rear->next=r;
r->next=null;
q->rear=r;
chess[x][y+1]=twtype;
num--;
}
if(num==4){
break;再判斷一遍,找不到就退出
}
t=t->next;
x=t->x;
y=t->y;
printf("%d,%d\n",x,y);
}
t=q->front->next;//先記錄一下這個頭
int count=0;
printf("該塊有以下元素:\n");
while(q->rear!=q->front){
lqnode *s;
s=q->front->next;
x=s->x;
y=s->y;
//上下左右都找一遍,註意條件,有些在邊上,比如【0】【0】這個點x-1是找不到的
if(chess[x+1][y]==0 && x+1>=0 && y>=0){
count++;
chess[x+1][y]=9; //找過的標記一下,以防再找一遍
}
if(chess[x][y+1]==0 && x>=0 && y+1>=0) {
count++;
chess[x][y+1]=9;
}
if(chess[x][y-1]==0 && x>=0 && y-1>=0) {
count++;
chess[x][y-1]=9;
}
if(chess[x-1][y]==0 && x-1>=0 && y>=0) {
count++;
chess[x-1][y]=9;
}
q->front->next=s->next;
printf("x=%d,y=%d\n",x,y);
//出隊列嘍
if(s->next==null){
q->rear=q->front;
}
}
printf("該塊有%d口氣\n",count);
if(count==0){//如果為0,就是被對方圍住啦,裡面所有的都要變為0,就是裡面的棋子都要被拿走
while(t!=null){//這個就是上面那個t為什麼要被記錄下來的原因
x=t->x;
y=t->y;
chess[x][y]=0;
t=t->next;
}
}
//以下就是再迴圈,找到沒有被記錄過並且還是黑放下的棋的點,
x=-1;
y=-1;
flag=1;
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(chess[i][j]==type && flag==1){//因為之前被找過的已經記錄過了
x=i;
y=j;
flag=0;
}
}
}
if(x==-1&&y==-1){
total=1;//如果找不到就是退出迴圈辣
}
}
}
最後再解釋一下
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
if(chess[i][j]==9 ||chess[i][j]==6 ||chess[i][j]==3)
{chess[i][j]=savechess[i][j];}
}
}
這一部分。
因為在lumpgas()函數里有記錄的痕跡,所以要把記錄的點都變成以前的,然後就是說一定要有記錄,因為當一方的棋被圍住了,所有被圍住的棋都是要清掉的,清掉這個功能也是在函數里實現的