[c]C语言提高效率和减少代码size的方法

C语言提高代码效率的几种方法

一段完美的代码不仅在于找到一个给定的问题的解决方案,但在它的简单性,有效性,紧凑性和效率(内存)。设计的代码比实际执行更难。因此,每一个程序员当用C语言开发时,都应该保持这些基本的东西在头脑中。本文向你介绍规范你的C代码的5种方法。


1、在可能的情况下使用typedef替代macro.当然有时候你无法避免macro,但是typedef更好。

typedefint* INT_PTR;INT_PTR a ,b;# define INT_PTR int*;INT_PTR a ,b;
在这个宏定义中,a是一个指向整数的指针,而b是只有一个整数声明。使用typedef ab都是整数的指针。

2
、在一个逻辑条件语句中常数项永远在左侧。

int x = 4;if
x = 1{ x = x + 2;printf"%d",x);// Output is 3 }

int x = 4;if
1 = x{ x = x + 2;printf"%d",x);
// Compilation error }

使用"="赋值运算符,替代"=="相等运算符,这是个常见的输入错误。常数项放在左侧,将产生一个编译时错误,让你轻松捕获你的错误。注:"="是赋值运算符。b = 1会设置变量b等于值1. "=="相等运算符。如果左侧等于右侧,返回true,否则返回false.


3
、确保声明和定义是静态的,除非您希望从不同的文件中调用该函数。

在同一文件函数对其他函数可见,才称之为静态函数。它限制其他访问内部函数,如果我们希望从外界隐藏该函数。现在我们并不需要为内部函数创建头文件,其他看不到该函数。

静态声明一个函数的优点包括:

A
)两个或两个以上具有相同名称的静态函数,可用于在不同的文件。

B
)编译消耗减少,因为没有外部符号处理。

4
、节约内存(内存对齐和填充的概念)

struct { char c;inti;short s;}str_1;struct { char c;shorts;inti;}str_2;
假设一个字符需要1个字节,short占用2个字节和int需要4字节的内存。起初,我们会认为上面定义的结构是相同的,因此占据相同数量的内存。然而,而str_1占用12个字节,第二个结构只需要8个字节?这怎么可能呢?

请注意,在第一个结构,3个不同的4个字节被分配到三种数据类型,而在第二个结构的前4个自己charshort可以被采用,int可以采纳在第二个的4个字节边界(一共8个字节)。

5
、使用无符号整数,而不是整数的,如果你知道的值将永远是否定的。

有些处理器可以处理无符号的整数比有符号整数的运算速度要快。(这也是很好的实践,帮助self-documenting代码)。

 

嵌入开发中C可以提高效率和减少代码size的方法

  1 switch-case语句。在程序中经常会使用switch-case语句,每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就浪费了处理器时间。为了提高速度,可以把具体的情况按照它们发生的相对频率排序。即把最可能发生的情况放在第一,最不可能发生的情况放在最后,这样会减少平均的代码执行时间。
  2全局变量。使用全局变量比向函数传递参数更加有效率,这样做去除了函数调用前参数入栈和函数完成后参数出栈的需要。当然,使用全局变量会对程序有一些负作用。
  3嵌入式系统编程应避免使用标准库例程,因为很多大的库例程设法处理所有可能的情况,所以占用了庞大的内存空间,因而应尽可能地减少使用标准库例程。
    (1) Inline
函数

   C++中,关键字Inline可以被加入到任何函数的声明中。这个关键字请求编译器用函数内部的代码替换所有对于指出的函数的调用。这样做在两个方面快于函数调用。这样做在两个方面快于函数调用:第一,省去了调用指令需要的执行时间;第二,省去了传递变元和传递过程需要的时间。但是使用这种方法在优化程序速度的同时,程序长度变大了,因此需要更多的ROM。使用这种优化在Inline函数频繁调用并且只包含几行代码的时候是最有效的。 

    (2)用指针代替数组

   在许多种情况下,可以用指针运算代替数组索引,这样做常常能产生又快又短的代码。与数组索引相比,指针一般能使代码速度更快,占用空间更少。使用多维数组时差异更明显。下面的代码作用是相同的,但是效率不一样。
   
数组索引               指针运算
    For(;;){                p=array
    A=array[t++];           for(;;){
                                 a=*(p++);
    ......                    ......
    }                       }

   指针方法的优点是,array的地址每次装入地址p后,在每次循环中只需对p增量操作。在数组索引方法中,每次循环中都必须进行基于t值求数组下标的复杂运算。
    (3)
不定义不使用的返回值

    function函数定义并不知道函数返回值是否被使用,假如返回值从来不会被用到,应该使用void来明确声明函数不返回任何值。

    (4)手动编写汇编

   在嵌入式软件开发中,一些软件模块最好用汇编语言来写,这可以使程序更加有效。虽然C/C++编译器对代码进行了优化,但是适当的使用内联汇编指令可以有效的提高整个系统运行的效率。
    (5)
使用寄存器变量

   在声明局部变量的时候可以使用register关键字。这就使得编译器把变量放入一个多用途的寄存器中,而不是在堆栈中,合理使用这种方法可以提高执行速度。函数调用越是频繁,越是可能提高代码的速度。
    (6)
使用增量和减量操作符

   在使用到加一和减一操作时尽量使用增量和减量操作符,因为增量符语句比赋值语句更快,原因在于对大多数CPU来说,对内存字的增、减量操作不必明显地使用取内存和写内存的指令,比如下面这条语句:
    x=x+1;
   
模仿大多数微机汇编语言为例,产生的代码类似于:
    move A,x      ;
x从内存取出存入累加器A
    add A,1       ;
累加器A
1
    store x       ;
把新值存回x

   如果使用增量操作符,生成的代码如下:
    incr x        ;x
1
   
显然,不用取指令和存指令,增、减量操作执行的速度加快,同时长度也缩短了。

    (7)减少函数调用参数

   使用全局变量比函数传递参数更加有效率。这样做去除了函数调用参数入栈和函数完成后参数出栈所需要的时间。然而决定使用全局变量会影响程序的模块化和重入,故要慎重使用。
    (8)Switch
语句中根据发生频率来进行case排序

    switch语句是一个普通的编程技术,编译器会产生if-else-if的嵌套代码,并按照顺序进行比较,发现匹配时,就跳转到满足条件的语句执行。使用时需要注意。每一个由机器语言实现的测试和跳转仅仅是为了决定下一步要做什么,就把宝贵的处理器时间耗尽。为了提高速度,没法把具体的情况按照它们发生的相对频率排序。换句话说,把最可能发生的情况放在第一位,最不可能的情况放在最后。
    (9)
将大的switch语句转为嵌套switch语句

   switch语句中的case标号很多时,为了减少比较的次数,明智的做法是把大switch语句转为嵌套switch语句。把发生频率高的case标号放在一个switch语句中,并且是嵌套switch语句的最外层,发生相对频率相对低的case标号放在另一个switch语句中。比如,下面的程序段把相对发生频率低的情况放在缺省的case标号内。         pMsg=ReceiveMessage();
        switch (pMsg->type)
        {
        case FREQUENT_MSG1:
        handleFrequentMsg();
        break;
        case FREQUENT_MSG2:
        handleFrequentMsg2();
        break;
        ......
        case FREQUENT_MSGn:
        handleFrequentMsgn();
        break;
        default:                      //
嵌套部分用来处理不经常发生的消息

        switch (pMsg->type)
        {
        case INFREQUENT_MSG1:
        handleInfrequentMsg1();
        break;
        case INFREQUENT_MSG2:
        handleInfrequentMsg2();
        break;
        ......
        case INFREQUENT_MSGm:
        handleInfrequentMsgm();
        break;
        }
        }
    
如果switch中每一种情况下都有很多的工作要做,那么把整个switch语句用一个指向函数指针的表来替换会更加有效,比如下面的switch语句,有三种情况:
        enum MsgType{Msg1, Msg2, Msg3}
        switch (ReceiveMessage()
        {
        case Msg1;
        ......
        case Msg2;
        .....
        case Msg3;
        .....
        }

    为了提高执行速度,用下面这段代码来替换这个上面的switch语句。

        /*准备工作*/
        int handleMsg1(void);
        int handleMsg2(void);
        int handleMsg3(void);
        /*
创建一个函数指针数组
*/
        int (*MsgFunction [])()={handleMsg1, handleMsg2, handleMsg3};
        /*
用下面这行更有效的代码来替换switch语句
*/
        status=MsgFunction[ReceiveMessage()]();

     (10)避免使用C++的昂贵特性

     C++在支持现代软件工程、OOP、结构化等方面对C进行了卓有成效的改进,但在程序代码容量、执行速度、程序复杂程度等方面比C语言程序性能差一些。并不是所有的C++特性都是昂贵的。比如,类的定义是完全有益的。公有和私有成员数据及函数的列表与一个 struct 及函数原形的列表并没有多大的差别。单纯的加入类,既不会影响代码的大小,也不会影响程序的效率。但C++的多重继承、虚拟基类、模板、异常处理及运行类型识别等特性对代码的大小和效率有负面的影响,因此对于C++的一些特性要慎重使用,可做些实验看看它们对应用程序的影响。

 
如何提高代码效率

代码效率包括两个方面内容:代码的大小和代码执行速度。如果代码精简和执行速度快,我们就说这个代码效率高。一般情况下,代码精简了速度也相应提上来了。单片机的ROM和RAM的空间都很有限,当您编程时遇到单片机的ROM和RAM的不够用的时候,或者您的程序要求较高的执行速度时,我们就得面对解决代码效率问题了。如何提高代码效率?现笔者以一个LED闪烁的程序为例与您探讨。

 #i nclude<reg52.h>//包含头文件

 sbit led=P2^0;//定义位变量led,使其关联单片机管脚P2.0

 void Delayms(unsigned int t);//声明延时函数

 int main(void)//主函数(C语言程序入口函数)

 {

       while(1)

       {

             led=0;//P2.0拉低,点亮LED

             Delayms(500);//调用延时函数,延时500毫秒

             led=1;//P2.0拉高,熄灭LED

             Delayms(500);//调用延时函数,延时500毫秒

       }

       return 0;

 }

void Delayms(unsigned int t)//定义延时函数

{

        unsigned int i,j;

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

               for(j=0;j<120;j++);//大约延时1毫秒

}

这是指示灯LED闪烁的C源码,这个源码在Keil uVision4 生成的程序代码是67个字节。下面我们就采用几个方法来提高这个程序的效率。

一.尽量定义局部变量

单片机程序的全局变量一般是放在通用数据存储器(RAM)中,而局部变量一般是放在特殊功能寄存器当中。处理寄存器数据的速度比处理RAM数据要快,如果在一个局部函数里调用一个全局变量将会多生成好几个代码出来。所以,少定义全局变量,多定义局部变量。如上例中,如果把延时函数里的i和j定义为全局变量,编译后程序代码会增加到79个字节,多了12个字节。

二.省略函数声明

在一个单片机程序里我们习惯在main函数的前面先声明被调用函数,然后在mian函数的下面再定义被调用函数。这样的写法固然是一个好习惯,但每声明一个函数会增加几个代码,而且函数形参数据类型越大、形参越多增加的代码就越多,显然这不是什么好事。如果不声明编译器又报错,怎么办?C编译器的编译顺序是从上往下编译,只要被调用的函数在主调函数调用之前定义就没有问题了。所以,笔者的习惯写法是不用事先声明函数,但要按先后顺序(被调用函数一定要在主调函数之前写好)来写函数定义,到最后再写main函数。这样做编译器不但不会报错,而且代码得到精简了。如上例中,把延时函数的声明删除了,然后把延时函数的定义搬到main函数的上面,编译后程序代码变成63个字节,减少了4个字节。

三.省略函数形参

函数带形参,是为了在函数调用时传递实参,不但可以避免重复代码出现,还可以通过传递不同的实参值多次调用函数且实现不同的函数功能,总体代码也会得到精简。在实际编程的时候,我们只要注意,还可以进一步精简代码。对于不是多次调用或者多次调用但实参值不变的函数我们可以省略函数形参。如上例中的延时函数,我们把它改成不带形参的函数:

void Delayms(void)//定义延时函数

 {

     unsigned int i,j;

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

          for(j=0;j<120;j++);//大约延时1毫秒

 }

编译后,程序代码变成了56个字节,减少了11个字节。

四.改换运算符

也许您可能没有注意到C运算符的运用也会影响程序代码的数量。如上例中,把延时函数里的自加运算符改成自减运算符后,如:

void Delayms(unsigned int t)//定义延时函数

 {

     unsigned int i,j;

     for(i=t;i>0;i--)

          for(j=120;j>0;j--);//大约延时1毫秒

 }

编译后,程序代码变成了65个字节,减少了2个字节。

通过改换运算符能达到精简代码的例子还有:

1.把求余运算表达式改为位与运算表达式。如:b=a%8 可以改为:b=a&7。

2.把乘法运算表达式改为左移运算表达式。如:b=a*8 可以改为:b=a<<3。

3.把除法运算表达式改为右移运算表达式。如:b=a/8 可以改为:b=a>>3。

五.选择合适的数据类型

C语言里选择变量的数据类型很讲究,变量的数据类型过小满足不了程序的要求,变量的数据类型过大会占用太多的RAM资源。您可能还没有注意到数据类型定义也影响程序代码的大小,而且这个影响还不小。如上例中,延时函数里的局部变量j定义的数据类型明显偏大,如果把它由unsigned int改成unsigned char 。编译后,程序代码变成了59个字节,减少了8个字节。

六.直接嵌入代码

    在您的程序里如果某个函数只调用一次,而您又要求代码提高执行速度,建议您不要采用调用函数的形式,而应该将该函数里的代码直接嵌入主调函数里,代码执行效率会大大提高。

七.使用效率高的C语句

C语言里有一个三目运算符“?”,俗称“问号表达式”。很多程序员都很喜欢使用,因为它逻辑清晰表达简洁。

看这个问号表达式:c=(a>b) ? a+1 : b+1;实际上等效于以下的if…else结构:

if (a>b)  c=a+1;

else  c=b+1;

可以看到,使用问号表达式,语句相当简洁,但它的执行效率却很低,远没有if…else语句效率高。所以,当您的程序要求提高执行速度的话,建议您不要使用问号表达式了。

另外,do…while语句也比while语句的效率高。

代码的效率问题,不是我们编程中的主要问题,除了程序要求较高的执行速度或者单片机的ROM和RAM不够用的时候才会考虑。一般情况下,我们不用在乎。如果您一味追求高效率的代码,可能会影响代码的可读性和可维护性。

### 回答1: 以下是一个简单的C语言实现六子棋α-β剪枝的代码代码中使用了一个双重递归函数,其中alpha和beta是剪枝参数。这个函数在每个节点上执行,并尝试通过剪枝来减少搜索空间。在搜索树的每一层上,它从所有可能的动作中选择一个动作,并将其应用于当前状态。然后它递归地调用自身,以查找下一层的最佳动作。如果一个节点的值被剪枝,则不需要再搜索该节点的子树,因为已经知道它的值不会优于其他节点。 ``` #include <stdio.h> #include <stdlib.h> #include <limits.h> #define BOARD_SIZE 6 #define MAX_DEPTH 4 typedef struct { int board[BOARD_SIZE][BOARD_SIZE]; } State; int evaluate(State state) { // TODO: Implement a heuristic evaluation function return 0; } int alphabeta(State state, int depth, int alpha, int beta, int maximizingPlayer) { if (depth == 0) { return evaluate(state); } if (maximizingPlayer) { int value = INT_MIN; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (state.board[i][j] == 0) { state.board[i][j] = 1; value = max(value, alphabeta(state, depth - 1, alpha, beta, 0)); state.board[i][j] = 0; alpha = max(alpha, value); if (beta <= alpha) { break; } } } } return value; } else { int value = INT_MAX; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (state.board[i][j] == 0) { state.board[i][j] = -1; value = min(value, alphabeta(state, depth - 1, alpha, beta, 1)); state.board[i][j] = 0; beta = min(beta, value); if (beta <= alpha) { break; } } } } return value; } } int main() { State initialState = {0}; // Initialize the board to all zeros int bestValue = alphabeta(initialState, MAX_DEPTH, INT_MIN, INT_MAX, 1); printf("Best value: %d\n", bestValue); return 0; } ``` 现在我们来详细解释一下代码中的每个部分。 首先我们定义了一个State结构体来表示游戏状态。它包含一个二维数组,表示六子棋棋盘上每个位置的状态。0表示该位置为空,1表示该位置为黑子,-1表示该位置为白子。 ``` typedef struct { int board[BOARD_SIZE][BOARD_SIZE]; } State; ``` 接下来,我们实现了一个evaluate函数,用于评估当前游戏状态的好坏。该函数应该根据当前状态返回一个分数,表示该状态的好坏。这是一个关键函数,因为它决定了如何搜索游戏树。如果它能够正确地评估状态的好坏,那么搜索算法就可以更快地找到最佳动作。 ``` int evaluate(State state) { // TODO: Implement a heuristic evaluation function return 0; } ``` 接下来,我们实现了一个alphabeta函数,用于执行α-β剪枝搜索。它采用当前状态、搜索深度、α和β剪枝参数以及一个布尔值maximizingPlayer作为输入。如果maximizingPlayer为true,则它正在搜索玩家的最佳动作。如果maximizingPlayer为false,则它正在搜索对手的最佳动作。 ``` int alphabeta(State state, int depth, int alpha, int beta, int maximizingPlayer) { if (depth == 0) { return evaluate(state); } if (maximizingPlayer) { int value = INT_MIN; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (state.board[i][j] == 0) { state.board[i][j] = 1; value = max(value, alphabeta(state, depth - 1, alpha, beta, 0)); state.board[i][j] = 0; alpha = max(alpha, value); if (beta <= alpha) { break; } } } } return value; } else { int value = INT_MAX; for (int i = 0; i < BOARD_SIZE; i++) { for (int j = 0; j < BOARD_SIZE; j++) { if (state.board[i][j] == 0) { state.board[i][j] = -1; value = min(value, alphabeta(state, depth - 1, alpha, beta, 1)); state.board[i][j] = 0; beta = min(beta, value); if (beta <= alpha) { break; } } } } return value; } } ``` 该函数使用递归方式搜索游戏树。如果搜索深度达到最大深度,则返回当前状态的评估值。否则,如果maximizingPlayer为true,则从当前状态的所有可能动作中选择一个动作,并递归地调用自身来查找下一层的最佳动作。在递归调用返回后,它更新alpha参数并检查是否可以剪枝。如果beta小于等于alpha,则它返回当前节点的值。如果maximizingPlayer为false,则执行类似的操作,但这次是搜索对手的最佳动作。它选择一个动作,并递归地调用自身来查找下一层的最佳动作。在递归调用返回后,它更新beta参数并检查是否可以剪枝。如果beta小于等于alpha,则它返回当前节点的值。 最后,我们在main函数中调用alphabeta函数,传递初始状态、最大深度以及α和β的初始值。该函数返回最佳动作的分数。我们可以使用这个分数来选择最佳动作。 ``` int main() { State initialState = {0}; // Initialize the board to all zeros int bestValue = alphabeta(initialState, MAX_DEPTH, INT_MIN, INT_MAX, 1); printf("Best value: %d\n", bestValue); return 0; } ``` 这是一个非常简单的例子,但它展示了如何使用α-β剪枝搜索来解决六子棋问题。在实践中,您需要实现更复杂的评估函数,并使用更多的搜索深度来获得更好的结果。 ### 回答2: C语言实现六子棋α-β剪枝的代码并详细解释 六子棋是一种双人对弈游戏,类似于五子棋。α-β剪枝是一种搜索树剪枝算法,可以在搜索树中减少无用的搜索步骤,提高搜索效率。 首先,我们需要定义棋盘和棋子的数据结构。 ```c #define SIZE 6 typedef struct { int x; int y; } Point; typedef struct { char board[SIZE][SIZE]; Point move; } State; ``` 然后,我们需要定义评估函数,用于评估当前局面的分数。 ```c int evaluate(State state) { // 根据当前局面评估分数 // 实现自己的评估算法 } ``` 接下来,我们需要定义最大值算法和最小值算法,分别代表电脑和玩家的决策过程。 ```c int max_value(State state, int alpha, int beta) { if (terminal_state(state)) { return evaluate(state); } int value = INT_MIN; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { if (is_valid_move(state, i, j)) { State new_state = make_move(state, i, j); int min_val = min_value(new_state, alpha, beta); if (min_val > value) { value = min_val; if (value > alpha) { alpha = value; } if (alpha >= beta) { return value; } } } } } return value; } int min_value(State state, int alpha, int beta) { if (terminal_state(state)) { return evaluate(state); } int value = INT_MAX; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { if (is_valid_move(state, i, j)) { State new_state = make_move(state, i, j); int max_val = max_value(new_state, alpha, beta); if (max_val < value) { value = max_val; if (value < beta) { beta = value; } if (alpha >= beta) { return value; } } } } } return value; } ``` 最后,我们需要定义主函数来调用最大值算法和最小值算法。 ```c int main() { State initial_state; // 初始化棋盘 while (!game_over) { Point move = get_player_move(); make_move(initial_state, move.x, move.y); Point best_move = alpha_beta_search(initial_state); make_move(initial_state, best_move.x, best_move.y); } return 0; } ``` 以上就是使用C语言实现六子棋α-β剪枝的代码及其详细解释。其中,评估函数在实际应用中需要根据具体情况进行设计,最大值算法和最小值算法配合α-β剪枝可以大幅度提高搜索效率,在棋类游戏等决策问题中具有重要作用。 ### 回答3: C语言实现六子棋α-β剪枝的代码并详细解释如下: ```c #include<stdio.h> #include<stdlib.h> // 定义棋盘大小和玩家 #define ROWS 8 #define COLS 8 #define EMPTY 0 #define PLAYER_X 1 #define PLAYER_O 2 // 评估函数,用于估计当前棋局对玩家X的价值 int evaluate(int chessboard[][COLS], int player) { // 获取玩家X和玩家O在棋盘上的得分 int player_x_score = 0; int player_o_score = 0; // 在代码中计算每个玩家在所有可能的连续六个位置上所得分 // 并将这些得分累加到各自的总分中 // ... // 返回玩家X的得分减去玩家O的得分作为棋局的评估值 return player_x_score - player_o_score; } // α-β剪枝搜索函数,用于预测接下来的最佳行动 int alpha_beta_search(int chessboard[][COLS], int depth, int alpha, int beta, int player) { // 判断是否达到了搜索的最深深度或者游戏结束 if (depth == 0 || game_over(chessboard)) { return evaluate(chessboard, PLAYER_X); } // 如果是玩家X的回合,即极大节点 if (player == PLAYER_X) { int max_eval = INT_MIN; // 对于每一个合法的行动 for (int i = 0; i < ROWS; i++) { for (int j = 0; j < COLS; j++) { if (valid_move(chessboard, i, j)) { // 在复制的棋盘上做出这一行动 chessboard[i][j] = player; // 调用递归搜索下一层,当前玩家为玩家O int eval = alpha_beta_search(chessboard, depth - 1, alpha, beta, PLAYER_O); // 恢复棋盘 chessboard[i][j] = EMPTY; // 更新最大值和alpha值 if (eval > max_eval) { max_eval = eval; } if (eval > alpha) { alpha = eval; } // 进行剪枝 if (alpha >= beta) { break; } } } } return max_eval; } // 如果是玩家O的回合,即极小节点,代码类似于玩家X的回合 else { int min_eval = INT_MAX; // ... return min_eval; } } // 可以实现其他辅助函数,如判断游戏是否结束、判断行动是否合法等 int main() { // 初始化棋盘和其他变量 // ... // 调用alpha_beta_search函数搜索最佳行动 int best_move = alpha_beta_search(chessboard, depth, INT_MIN, INT_MAX, PLAYER_X); // 执行最佳行动 // ... return 0; } ``` 以上是使用C语言实现六子棋α-β剪枝的简单代码框架。主要思路是通过递归地搜索棋盘的各种可能性,并使用α-β剪枝进行优化以减少搜索空间。其中,evaluate函数用于评估当前局面对玩家X的价值,根据得分的差异来评估棋局的优劣。alpha_beta_search函数实现了α-β剪枝算法,根据当前节点是极大节点还是极小节点,进行不同的操作。在玩家X的回合,遍历所有合法行动,对每个行动进行搜索,并更新最大值和alpha值,同时进行剪枝。在玩家O的回合,代码与玩家X的回合类似,只是更新最小值和beta值。最后通过调用alpha_beta_search函数从当前局面中搜索出最佳行动,并执行该行动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值