printf 游戏

很多人都觉得编游戏很高深…其实不然…

以下是文曦畅初学C时写个一个九格游戏

涉及的知识只有函数,各种流程控制.

基本不涉及图形的知识.

我只想说明一个问题:不要觉得你学得不够多,只是,你没有充分利用你所学到的

虽然类似的代码我也写过,不过没有他写的好,所以还是发他的好了.

以下代码在 TC2 + winXP 通过.

#include <stdio.h>

#include <stdlib.h>    /*使用其中的int random(int a):

产生一个在0到a-1之间的整数

和 randomize():复位随机发生器*/

#include <conio.h>    /*使用其中的gotoxy(int x,int y):

把光标移动到屏幕的x(1~80),y(1~25/50)处*/

/*和clrscr():清屏*/

int num[]={1,2,3,4,5,6,7,8,0};    /*方块的数字*/

main(){

    char key=0;    /*键盘码*/

    int pos;    /*九格中,空格的位置*/

    clrscr();    /*清屏*/

    randomize();    /*初始化随机发生器*/

    newGame();

    for(;;){

        key=getch();    /*获得键盘输入*/

        if(key==0) continue;

        pos=GetTheNull();    /*得到空格*/

        switch(key){        /*测试按键*/

            case 72:    /*按下*/

                if(pos<=5) change(pos,pos+3);

                break;

            case 80:    /*按上*/

                if(pos>=3) change(pos,pos-3);

                break;

            case 77:    /*按左*/

                if(pos%3!=0) change(pos,pos-1);

                break;

            case 75:    /*按右*/

                if(pos%3!=2) change(pos,pos+1);

                break;

            case 110:    /*按下‘n’新建游戏*/

                newGame();

        }

        update();    /*更新*/

        if(isSuccess()){    /*看是否游戏成功*/

            gotoxy(26,10);    /*成功了,输出一个写有Well done!的外框*/

            printf(“\332\304\304\304\304\304\304\304\304\304\304\304\304\267”);

            gotoxy(26,11);

            printf(“\263            \272”);

            gotoxy(26,12);

            printf(“\263 Well Done! \272”);

            gotoxy(26,13);

            printf(“\263            \272”);

            gotoxy(26,14);

            printf(“\324\315\315\315\315\315\315\315\315\315\315\315\315\274\n”);

            getch();

            newGame();    /*新游戏*/

        }

        if(key==27) break;    /*退出*/

    }

    clrscr();    /*清屏*/

}

newGame(){    /*新建游戏,实际上就是把有数字的八个方格打散,

这种效果的实现就是随机的两两交换,而怎么不与空的那个交换呢?

这涉及有没有解的问题

不管怎么样,九格游戏最后的结果只有两个:

123 | 123

456 | 456

78  | 87    (证明从略)

而要两两交换而始终有解的话,(从原序列开始)必须:相邻交换的次数为偶

但我们用一种更有效的方法:

每一个总与其下第二个交换.

第7,8个与0,1交换,只要交换次数多,仍可获得相同的效果.

而这些的前提是其中的0不能与其第奇数个作奇数次交换.

为了省事,不处理0…

其中产道理,请自己思考

*/

    int i,a,b;

    for(i=0;i<8;i++) num=i+1;

    num[8]=0;    /*将数组复原*/

    for(i=0;i<300;i++){

        a=random(8);    /*产生随机数*/

        b=(a+2)%8;    /*得到下第二个的数组下标*/

        change(a,b);    /*交换*/

    }

    update();

}

update(){    /*在屏幕上画出整个九格图像,关于定位的问题自己分析*/

    int i,j;

    for(i=0;i<=2;i++){

        gotoxy(24,8+i*3);

        for(j=0;j<=2;j++){

            if (num[j+i*3]!=0)

                printf(“\332\304\304\304\304\267”);

            else

                printf(”      “);

        }

        gotoxy(24,9+i*3);

        for(j=0;j<=2;j++){

            if (num[j+i*3]!=0)

                printf(“\263 %d  \272”,num[j+i*3]);

            else

                printf(”      “);

        }

        gotoxy(24,10+i*3);

        for(j=0;j<=2;j++){

            if (num[j+i*3]!=0)

                printf(“\324\315\315\315\315\274”);

            else

                printf(”      “);

        }

        printf(“\n”);

    }

}

int isSuccess(){    /*判断是否游戏*/

    int i,ret=1;

    for(i=0;i<8;i++)

        ret=ret&&(num==(i+1));

    return ret;

}

int GetTheNull(){    /*获得空格的位置*/

    int i;

    for(i=0;i<=8;i++){

        if (num==0)

            return i;

    }

}

change(int a,int b){    /*交换num[a],num*/

    int temp;

    temp=num[a];

    num[a]=num;

    num=temp;

}

/*游戏,就这么简单!*/

另外说明:

/324/315…之类的东西,代表的是ASCII表中的制表符.

当然,它是八进制的.