CCF-CSP-2018-3-4 棋局评估

19人阅读 评论(0) 收藏 举报
分类:

题目:

时间限制:1.0s
内存限制:256.0MB
问题描述:
问题描述
  Alice和Bob正在玩井字棋游戏。
  井字棋游戏的规则很简单:两人轮流往3*3的棋盘中放棋子,Alice放的是“X”,Bob放的是“O”,Alice执先。当同一种棋子占据一行、一列或一条对角线的三个格子时,游戏结束,该种棋子的持有者获胜。当棋盘被填满的时候,游戏结束,双方平手。
  Alice设计了一种对棋局评分的方法:
  - 对于Alice已经获胜的局面,评估得分为(棋盘上的空格子数+1);
  - 对于Bob已经获胜的局面,评估得分为 -(棋盘上的空格子数+1);
  - 对于平局的局面,评估得分为0;


  例如上图中的局面,Alice已经获胜,同时棋盘上有2个空格,所以局面得分为2+1=3。
  由于Alice并不喜欢计算,所以他请教擅长编程的你,如果两人都以最优策略行棋,那么当前局面的最终得分会是多少?
输入格式
  输入的第一行包含一个正整数T,表示数据的组数。
  每组数据输入有3行,每行有3个整数,用空格分隔,分别表示棋盘每个格子的状态。0表示格子为空,1表示格子中为“X”,2表示格子中为“O”。保证不会出现其他状态。
  保证输入的局面合法。(即保证输入的局面可以通过行棋到达,且保证没有双方同时获胜的情况)
  保证输入的局面轮到Alice行棋。
输出格式
  对于每组数据,输出一行一个整数,表示当前局面的得分。
样例输入
3
1 2 1
2 1 2
0 0 0
2 1 1
0 2 1
0 0 2
0 0 0
0 0 0
0 0 0
样例输出
3
-4
0
样例说明
  第一组数据:
  Alice将棋子放在左下角(或右下角)后,可以到达问题描述中的局面,得分为3。
  3为Alice行棋后能到达的局面中得分的最大值。
  第二组数据:


  Bob已经获胜(如图),此局面得分为-(3+1)=-4。
  第三组数据:
  井字棋中若双方都采用最优策略,游戏平局,最终得分为0。
数据规模和约定
  对于所有评测用例,1 ≤ T ≤ 5。

代码:

#include<iostream>
#include<string.h>
using namespace std;

int a[9],ans[3][3][3][3][3][3][3][3][3];

int isend()
{
	for (int i = 0; i < 3; i++)if (a[i] == a[i + 3] && a[i] == a[i + 6] && a[i])return a[i];
	for (int i = 0; i < 9; i += 3)if (a[i] == a[i + 1] && a[i] == a[i + 2] && a[i])return a[i];
	if (a[0] == a[4] && a[4] == a[8] && a[4])return a[4];
	if (a[2] == a[4] && a[4] == a[6] && a[4])return a[4];
	return 0;
}

int dp()
{
	if (ans[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]][a[8]]< 100)
		return ans[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]][a[8]];
	int s = 0;
	for (int i = 0; i < 9; i++)if (a[i])s++;
	if (isend() == 1)return 10 - s;
	if (isend() == 2)return s - 10;
	if (s == 9)return 0;
	int r;
	if (s % 2)
	{
		r = 100;
		for (int i = 0; i < 9; i++)
		{
			if (a[i])continue;
			a[i] = 2;
			if (r > dp())r = dp();
			a[i] = 0;
		}
	}
	else
	{
		r = -100;
		for (int i = 0; i < 9; i++)
		{
			if (a[i])continue;
			a[i] = 1;
			if (r < dp())r = dp();
			a[i] = 0;
		}
	}
	ans[a[0]][a[1]][a[2]][a[3]][a[4]][a[5]][a[6]][a[7]][a[8]] = r;
	return r;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		memset(ans, 1, sizeof(ans));
		for (int i = 0; i < 9; i++)cin >> a[i];
		cout << dp() << endl;
	}
	return 0;
}

查看评论

棋局评估

如果在叶子节点不能给出胜-负-和的结果,那“有利局面”的选择就只能依靠局面的评估了。通常设计的评估函数需要考虑如下不同类型的知识,并通过量化后加权组合而成。 1 子力(Material)  ...
  • u011002533
  • u011002533
  • 2017年01月12日 12:00
  • 198

【国象AI】评估函数(一)

先做个框=感觉有些是应该由搜索树去考虑的、也没做过这些所以有点困扰子力基础价值后900,车500,象325,马300,兵100子力交换这里的判断肯定得和,谁走有关系吧= =白行的时候,加分项黑方无保护...
  • birdy_
  • birdy_
  • 2017年08月24日 12:39
  • 378

游戏开发(三)——WIN32 黑白棋(一)——棋局逻辑的设计

今天以黑白棋为例,开始给一个win32的小游戏设计, 这里打算分3部分介绍 1、棋局的现实 2、AI的现实 3、游戏画面的现实 提供一下完整项目下载 其中第一部分为黑白棋游戏的主要逻辑: 1、棋...
  • zilaishuichina
  • zilaishuichina
  • 2014年07月28日 20:14
  • 2749

象棋军师app已经上线

如果你象棋下的不好,可以试试这个APP。首先在电脑上打开在线象棋例如QQ新中国象棋或者途游象棋,然后在APP中打开手机摄像头拍摄棋局,APP就会给你指出一步好棋,小朋友们要不要试试看。在Apple a...
  • baixiaozhe
  • baixiaozhe
  • 2016年11月11日 13:59
  • 1218

棋局

很多年前,我还年少的时候,喜欢下象棋,在学校里基本上我能下赢的,我总能下赢,我下不赢的,总也下不赢。不得其解,也慢慢懒得操练了。 后来有次学校搞业余活动,有个老师是省象棋协会的,组织了一节棋课。我去...
  • a2657222
  • a2657222
  • 2012年12月10日 18:55
  • 389

2井字棋(5分)

2井字棋(5分)题目内容:嗯,就是视频里说的那个井字棋。视频里说了它的基本思路,现在,需要你把它全部实现出来啦。你的程序先要读入一个整数n,范围是[3,100],这表示井字棋棋盘的边长。比如n=3就表...
  • qq_40071271
  • qq_40071271
  • 2018年03月07日 19:30
  • 26

C井字棋

#include #include int main() { char qipan[3][3] = {{' ',' ',' '},{' ',' ',' '},{' ',' ',' '}}...
  • sofeien
  • sofeien
  • 2015年08月05日 16:16
  • 330

CCF 井字棋

CCF CSP13 (4) 井字棋 补了一天算法课后的尝试 涉及算法:极大极小算法。 未进行剪枝等优化操作。 C/C++ code: #include&lt;iostream...
  • alegriabaile
  • alegriabaile
  • 2018年03月19日 20:23
  • 109

古代棋局

规则: 桌子上放六个匣子,编号是1至6。多位参与者(以下称玩家)可以把任意数量的钱押在某个编号的匣子上。 所有玩家都下注后,庄家同时掷出3个骰子(骰子上的数字都是1至6)。输赢规则如下: 1. ...
  • si444555666777
  • si444555666777
  • 2017年08月27日 20:47
  • 62

重温历史——计算机简史

大约在公元1700年左右某天,友人送给他一幅从中国带来图画,名称叫做“八卦”,是宋朝人邵雍所摹绘的一张“易图”。莱布尼茨用放大镜仔细观察八卦的每一卦象,发现它们都由阳(—)和阴(--)两种符号组合而...
  • u011474028
  • u011474028
  • 2017年06月11日 13:04
  • 821
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 112万+
    积分: 2万+
    排名: 423
    博客专栏