POJ 1568 极大极小搜索 + alpha-beta剪枝

极小极大搜索 的个人理解(alpha-beta剪枝)

主要算法依据就是根据极大极小搜索实现的。

苦逼的是,查了两个晚上的错,原来最终是判断函数写错了。。瞬间吐血!

ps. 据说加一句 if sum < 4 printf("#####\n")会变态的快,不过懒得加了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <utility>
#include <vector>
#include <queue>
#include <set>
#define INF 0x3f3f3f3f

using namespace std;

int map[4][4], sum, winx, winy;
char c;

bool check(int otherplayer)
{
    for(int i = 0; i < 4; i ++)
    {
        int tmp = 0;
        for(int j = 0; j < 4; j ++)
            tmp += (map[i][j] == otherplayer);
        if(tmp == 4)
            return 1;
    }
    for(int j = 0; j < 4; j ++)
    {
        int tmp = 0;
        for(int i = 0; i < 4; i ++)
            tmp += (map[i][j] == otherplayer);
        if(tmp == 4)
            return 1;
    }
    int tmp1 = 0, tmp2 = 0;
    for(int i = 0; i < 4; i ++)
    {
        tmp1 += (map[i][i] == otherplayer);
        tmp2 += (map[3-i][i] == otherplayer);
    }
    if(tmp1 == 4 || tmp2 == 4)
        return 1;
    return 0;
}

int alpha_beta(int depth, int alpha, int beta)
{
    int nowplayer = depth&1;
    if(check(1-nowplayer))
        return -1;
    if(sum == 16)
        return 0;
    for(int i = 0; i < 4; i ++)
        for(int j = 0; j < 4; j ++)
            if(map[i][j] == 2)
            {
                map[i][j] = nowplayer;
                sum ++;
                int tmp = -alpha_beta(depth+1, -beta, -alpha);
                map[i][j] = 2;
                sum --;
                if(tmp >= beta)
                    return beta;
                if(tmp > alpha)
                    alpha = tmp;
                if(depth == 0 && alpha == 1)
                {
                    winx = i, winy = j;
                    return alpha;
                }
            }
    return alpha;
}

int main()
{
    while(getchar() != ‘$‘)
    {
        sum = 0;
        getchar();
        for(int i = 0; i < 4; i ++)
            for(int j = 0; j < 4; j ++)
            {
                c = getchar();
                switch (c){
                    case ‘.‘:
                        map[i][j] = 2;
                        break;
                    case ‘x‘:
                        map[i][j] = 0;
                        sum ++;
                        break;
                    case ‘o‘:
                        map[i][j] = 1;
                        sum ++;
                }
                if(j == 3) getchar();
            }
        if(alpha_beta(0, -INF, INF) == 1)
            printf("(%d,%d)\n", winx, winy);
        else
            printf("#####\n");
    }
    return 0;
}

/*

?
....
.xo.
.ox.
....
?
o...
.ox.
.xxx
xooo
?
xxxo
oxox
....
xxxo
$

*/
时间: 2024-10-14 09:09:41

POJ 1568 极大极小搜索 + alpha-beta剪枝的相关文章

五子棋AI算法第三篇-Alpha Beta剪枝

剪枝是必须的 上一篇讲了极大极小值搜索,其实单纯的极大极小值搜索算法并没有实际意义. 可以做一个简单的计算,平均一步考虑 50 种可能性的话,思考到第四层,那么搜索的节点数就是 50^4 = 6250000,在我的酷睿I7的电脑上一秒钟能计算的节点不超过 5W 个,那么 625W 个节点需要的时间在 100 秒以上.电脑一步思考 100秒肯定是不能接受的,实际上最好一步能控制在 5 秒 以内. 顺便说一下层数的问题,首先思考层数必须是偶数.因为奇数节点是AI,偶数节点是玩家,如果AI下一个子不考

C++alpha beta剪枝算法 实现4*4 tic-tac-toe

先上一张alpha beta原理图,一看就懂 代码有点长,主要是因为算评估值得时候用的是穷举. 玩家是1,电脑是2,可以选择难度以及先手. // // main.cpp // Tic-Tac-Toe // // Created by mac on 2017/4/2. // Copyright ? 2017年 mac. All rights reserved. // #include <iostream> #include <vector> #include <math.h&g

POJ 1568 Find the Winning Move

Find the Winning Move 链接 题意: 4*4的棋盘,给出一个初始局面,问先手有没有必胜策略? 有的话输出第一步下在哪里,如果有多个,按(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1) ... 的顺序输出第一个.没有输出“#####”. 分析: 极大极小搜索,对抗搜索,α+β剪枝. 代码: 1 #include<cstdio> 2 3 char g[5][5]; 4 int ansx,ansy; 5 6 int judge() {

POJ 1564 Sum It Up (DFS+剪枝)

 Sum It Up Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5820   Accepted: 2970 Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4

极大极小搜索思想+(α/β)减枝 【转自-----https://blog.csdn.net/hzk_cpp/article/details/79275772】

极大极小搜索,即minimax搜索算法,专门用来做博弈论的问题的暴力. 多被称为对抗搜索算法. 这个搜索算法的基本思想就是分两层,一层是先手,记为a,还有一层是后手,记为b. 这个搜索是认为这a与b的利益关系是对立的,即假设a要是分数更大,b就要是分数更小. 而且这两个人都是用最优策略. 对,就是这样. 假设我们现在有一道题,给出一串数列,有两个选手按顺序选数,也就是一个选手选了ai,接下来另一个选手就必须选ai后面的任意一个数,然后每个选手选的数的累加和即为选手的分数,求先手比后手最多多几分.

扩增子分析解读6进化树 Alpha Beta多样性

分析前准备 # 进入工作目录 cd example_PE250 上一节回顾:我们的OTU获得了物种注释,并学习OTU表的各种操作————添加信息,格式转换,筛选信息. 接下来我们学习对OTU序列的进化分析.同时计算Alpha和Beta多样性值. 16. 进化树构建 进化树是基于多序列比对的结果,可展示丰富的信息,我们将在R绘图中详细解读.此处只是建树,用于Alpha, Beta多样性分析的输入文件. # clustalo多序列比对,如果没有请安装Clustal Omega clustalo -i

[CodeVs3196]黄金宝藏(状态压缩DP/极大极小搜索)

题目大意:给出n(≤500)个数,两个人轮流取数,每次可以从数列左边或者右边取一个数,直到所有的数被取完,两个人都以最优策略取数,求最后两人所得分数. 显然这种类型的博弈题,第一眼就是极大极小搜索+记忆化,但是我并不是很会极大极小搜索TAT.然后第二眼发现可以用状压写,而且显然比极大极小搜索好写啊.预处理出前缀和,然后f[i,j]表示从第i个数到第j个数先手可得到的最大得分,则有f[i,j]=sum[j]-sum[i-1]-min(f[i+1,j],f[i,j-1]);[第i个数到第j个数的和减

POJ 2329 (暴力+搜索bfs)

Nearest number - 2 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 3943 Accepted: 1210 Description Input is the matrix A of N by N non-negative integers. A distance between two elements Aij and Apq is defined as |i ? p| + |j ? q|. Your pro

POJ 2918 Tudoku [搜索]

和POJ2676一样哈,,, 原谅我水题目数 = =!... #include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> using namespace std; int map[10][10]; char tmp[10][10]; bool row[10][10]; bool col[10][10]; bool grid[10][10]; bool DFS(int