LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: scream

如何用c写一个算24的小游戏

[复制链接]
发表于 2003-12-27 14:36:06 | 显示全部楼层
上面两个程序,第一个修改了个笔误,调试倒是通过了。但是有点问题。
结果如下:
(9-8)*6+6=24
浮点数例外,为什么会有浮点数例外啊?
最近才开始linux下面的c/c++编程。
第二个编译也通过,不过运行结果如下:
[root@localhost cpp]# ./24-2
Enter four number!
6
9
8
3
段错误

段错误是什么意思啊?

我是在红旗4.0下做的。
请各位指点一下。
发表于 2003-12-28 03:28:02 | 显示全部楼层
楼主的程序似乎复杂了一点,不过精神可嘉。程序首先就是要能正常的工作,然后才考虑到算法的问题,如果工作都不正常,算法再好也是徒然。
后来的一位兄弟帖的算法,恕小弟愚昧,实在是看不懂的说,竟然还有从ARRAY[-N]中读值的!
我自己调试了一个,工作似乎还正常,大家测试测试吧。

  1. /*
  2. * This is just a game,to calculate 24,only support +,-,*,/
  3. *
  4. * Suppose A,B,C,D are numbers, a,b,c are operaters,there are cases as
  5. * follow:
  6. *
  7. * (A a B) b C c D -> (E b C) c D, E b (C c D)
  8. * A a (B b C) c D -> (A a E) c D, A a (E c D)
  9. * A a B b (C c D) -> A a (B b E), (A a B) b E
  10. *
  11. * because E b (C c D) == (A a B) b E,there are only 5 cases.
  12. *
  13. * Fog,Sun Dec 28 03:13:15 2003
  14. *
  15. */

  16. #include "stdio.h"

  17. #define false 0
  18. #define true  1

  19. /* ((A a B) b C) c D */
  20. #define DUMP_RESULT1()                                      \
  21. {                                                           \
  22.     printf("((%1.0f %c %1.0f) %c %1.0f) %c %1.0f = 24\n",   \
  23.        a[p1],op[o1-1],                                      \
  24.        a[p2],op[o2-1],                                      \
  25.        a[p3],op[o3-1],                                      \
  26.        a[p4]);                                              \
  27.     found=true;                                             \
  28. }

  29. /* (A a (B b C)) c D */
  30. #define DUMP_RESULT2()                                      \
  31. {                                                           \
  32.     printf("(%1.0f %c (%1.0f %c %1.0f)) %c %1.0f = 24\n",   \
  33.        a[p1],op[o1-1],                                      \
  34.        a[p2],op[o2-1],                                      \
  35.        a[p3],op[o3-1],                                      \
  36.        a[p4]);                                              \
  37.     found=true;                                             \
  38. }

  39. /* A a ((B b C) c D) */
  40. #define DUMP_RESULT3()                                      \
  41. {                                                           \
  42.     printf("%1.0f %c ((%1.0f %c %1.0f) %c %1.0f) = 24\n",   \
  43.        a[p1],op[o1-1],                                      \
  44.        a[p2],op[o2-1],                                      \
  45.        a[p3],op[o3-1],                                      \
  46.        a[p4]);                                              \
  47.     found=true;                                             \
  48. }

  49. /* A a (B b (C c D)) */
  50. #define DUMP_RESULT4()                                      \
  51. {                                                           \
  52.     printf("%1.0f %c (%1.0f %c (%1.0f %c %1.0f)) = 24\n",   \
  53.        a[p1],op[o1-1],                                      \
  54.        a[p2],op[o2-1],                                      \
  55.        a[p3],op[o3-1],                                      \
  56.        a[p4]);                                              \
  57.     found=true;                                             \
  58. }

  59. /* (A a B) b (C c D) */
  60. #define DUMP_RESULT5()                                      \
  61. {                                                           \
  62.     printf("(%1.0f %c %1.0f) %c (%1.0f %c %1.0f) = 24\n",   \
  63.        a[p1],op[o1-1],                                      \
  64.        a[p2],op[o2-1],                                      \
  65.        a[p3],op[o3-1],                                      \
  66.        a[p4]);                                              \
  67.     found=true;                                             \
  68. }

  69. float r(float a0, float a1, int o)
  70. {
  71.     if (o == 1)
  72.         return a0+a1;
  73.     else if (o == 2)
  74.         return a0-a1;
  75.     else if (o == 3)
  76.         return a0*a1;
  77.     else if (o == 4)
  78.         return a0/a1;

  79.     return 0;
  80. }   

  81. int main()
  82. {
  83.     float a[4];
  84.     char found = false;
  85.     char op[4];
  86.     int p1, p2, p3, p4;
  87.     int o1,o2,o3;
  88.    
  89.     printf("Enter four number!\n");
  90.     scanf("%f%f%f%f",&a[0],&a[1],&a[2],&a[3]);

  91.     op[0] = '+';
  92.     op[1] = '-';
  93.     op[2] = '*';
  94.     op[3] = '/';
  95.    
  96.     for(p1=0; p1<=3; p1++)
  97.     {
  98.         for(p2=0; p2<=3; p2++)
  99.         {
  100.             if (p2==p1)
  101.                 continue;
  102.             else
  103.                 for(p3=0; p3<=3; p3++)
  104.                 {
  105.                     if ((p3==p2)||(p3==p1))
  106.                         continue;
  107.                     else{
  108.                         p4 = 6 - p1 - p2 - p3;
  109.                         for(o1=1; o1<=4; o1++)
  110.                         {
  111.                             if (found == true) break;
  112.                             for(o2=1; o2<=4; o2++)
  113.                             {
  114.                                 if (found==true) break;   
  115.                                 for(o3=1; o3<=4; o3++)
  116.                                 {
  117.                                     if (found == true) break;
  118.                                     if (r(r(r(a[p1],a[p2],o1),a[p3],o2),a[p4],o3)==24)
  119.                                     {
  120.                                         DUMP_RESULT1();
  121.                                         break;
  122.                                     }
  123.                                     if (r(r(a[p1],r(a[p2],a[p3],o2),o1),a[p4],o3)==24)
  124.                                     {  
  125.                                         DUMP_RESULT2();
  126.                                         break;
  127.                                     }
  128.                                     if (r(a[p1],r(r(a[p2],a[p3],o2),a[p4],o3),o1)==24)
  129.                                     {  
  130.                                         DUMP_RESULT3();
  131.                                         break;
  132.                                     }                                    
  133.                                     if (r(a[p1],r(a[p2],r(a[p3],a[p4],o3),o2),o1)==24)
  134.                                     {
  135.                                         DUMP_RESULT4();
  136.                                         break;
  137.                                     }
  138.                                     if (r(r(a[p1],a[p2],o1),r(a[p3],a[p4],o3),o2)==24)
  139.                                     {
  140.                                         DUMP_RESULT5();
  141.                                         break;
  142.                                     }
  143.                                 }
  144.                             }
  145.                         }        
  146.                     }
  147.                     if (found == true) break;            
  148.                 }
  149.         }
  150.     }
  151.    
  152.     if (found == false)
  153.         printf("Ask god for the solution :-)\n");

  154.     return 0;
  155. }
复制代码
发表于 2003-12-28 13:02:26 | 显示全部楼层
测试正常。学习中。
发表于 2003-12-28 15:37:10 | 显示全部楼层
else if (o == 4)
        return a0/a1;
应该修改为
else if (o == 4&&a1!=0)
        return a0/a1;
否则对于5,5,5,5结果为
(5-5)/(5-5)=24拉。呵呵
发表于 2003-12-28 17:40:29 | 显示全部楼层
不错,bug一个。Thanks.
发表于 2004-2-6 10:51:06 | 显示全部楼层

我自己写的

注意程序是用后缀表达式计算,思路非常简单,穷举所有的数(这里会有重复),产生所有的后缀表达式的排列,计算后缀表达式我想大家没有任何的疑义,只是我没有写从后缀表达式转化韦中缀表达式的函数,因为我觉得这个不时算法的关键,这个代码穷举了所有的能够产生结果韦24的数据组合。

include <stdio.h>

#include <stdlib.h>



#define dim(list) (sizeof(list) / sizeof(list[0]))



/* typedef enum {add = 0, sub, multi, div}operator; */

static unsigned char operatortable[4] = {'+', '-', '*', '/'};

static unsigned char operatorlist[64][4];

static unsigned int operand[4];



static void genrate_operatorlist();

static void print_operatorlist();

static void genrate_operand();

static void test();

static float cal_expr(char operatorstack[4], const int size);

static void print_expr(char operatorstack[4]);



int main(){

    genrate_operatorlist();

    /* print_operatorlist(); */

    genrate_operand();

    test();

    return 0;

}



void genrate_operatorlist(){

    int i = 0, j = 0, k = 0, cnt =0;

    for (i = 0; i < dim(operatortable); ++i){

        for (j = 0; j < dim(operatortable); ++j){

                for (k = 0; k < dim(operatortable); ++k){

                        operatorlist[cnt][0] = operatortable;

                        operatorlist[cnt][1] = operatortable[j];

                        operatorlist[cnt][2] = operatortable[k];

                        operatorlist[cnt][3] = '\0';

                        cnt++;

                }

        }

    }

}



void print_operatorlist(){

        int i = 0, j = 0;

        for (i = 0; i < dim(operatorlist); ++i){

                for (j = 0; j < dim(operatorlist[0]); ++j){

                        printf("%c", operatorlist[j]);

                  }

                  printf("\n");

        }

}



void genrate_operand(){

        const int maxnum = 10;

    int i = 0, j = 0, k = 0, l = 0, cnt = 0;

    for (i = 1; i <= maxnum; ++i){

        for (j = 1; j <= maxnum; ++j){

                for (k = 1; k <= maxnum; ++k){

                        for (l = 1; l <= maxnum; ++l){

                                operand[0] = i;

                                operand[1] = j;

                                operand[2] = k;

                                operand[3] = l;

                                for(cnt = 0; cnt < dim(operatorlist); ++cnt){

                                        if (cal_expr(operatorlist[cnt], 3) == 24)

                                                print_expr(operatorlist[cnt]);

                                   }

                          }

                }

        }

    }       

}



void test(){

        FILE *fp;

        int cnt;

        if (!(fp = fopen("input.txt", "r"))){

                printf("\nCan not open input.txt\n");

                exit(-1);

        }

        while(!feof(fp)){

                if(1 > fscanf(fp, "%d %d %d %d", &operand[0], &operand[1], &operand[2], &operand[3]))

                                break;

        else{

                for(cnt = 0; cnt < dim(operatorlist); ++cnt){

                        if (cal_expr(operatorlist[cnt], 3) == 24)

                                print_expr(operatorlist[cnt]);

                }

                }

        }

        fclose(fp);

}



float cal_expr(char operatorstack[4], const int size){

        int i = 0, j = size;

        float result = operand[j--];

        for(i = 0; i < size; ++i, --j){

                switch(operatorstack){

                        case '+' : result += operand[j]; break;

                        case '-' : result -= operand[j]; break;

                        case '*' : result *= operand[j]; break;

                        case '/' : result /= operand[j]; break;

                        default : break;

                  }

        }

        return result;

}



void print_expr(char operatorstack[4]){

        int i = 0;

        for (i = 0; i < dim(operand); ++i){

                printf("%d", operand);

        }

        printf("%s\n", operatorstack);

}
发表于 2004-2-6 10:53:55 | 显示全部楼层

上面的代码经过了严格的调试。

很容易改造成判断四个数能否组合出24.
发表于 2004-4-22 22:08:46 | 显示全部楼层
罗列全部是最容易想到的方法,24点问题很明显是用来练算法的,至于要来软件工程的那一套,似乎小题大作了吧.
我还是一个学生,希望前辈指点.
发表于 2004-4-24 08:02:29 | 显示全部楼层
果然还是穷举
发表于 2004-4-24 08:31:13 | 显示全部楼层
果然还是穷举
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表