未来的背景
在2017年,您和您的对手将在一场只有未来一场生存的未来派枪战中对峙。您是否有足够的经验击败对手?现在是时候以您最喜欢的编程语言来提高您的枪支技能,并与一切斗争吧!
比赛结果
本次比赛在早上UTC 2月2日结束的第二,2017年由于我们的选手,我们有一个令人兴奋的未来的比赛!
经过与CBetaPlayer和StudiousPlayer的激烈角逐,MontePlayer是最终的赢家。三位关岛顶级决斗者拍摄了纪念照:
MontePlayer - by TheNumberOne
+------------+
CBetaPlayer | | - by George V. Williams
+------------+ # 1 | StudiousPlayer - by H Walters
| +----------------+
| # 2 # 3 |
+------------------------------------------+
The Futurustic Gun Duel @ PPCG.SE 2017
恭喜获奖者!详细的排行榜可以在本文结尾处看到。
一般指导
- 访问官方资源库以获取本比赛中使用的源代码。
- C ++条目:请继承
Player
该类。 - 非C ++条目:在非C ++提交的接口部分中选择一个接口。
- 当前允许使用非C ++语言:Python 3,Java。
决斗
- 每个玩家都从一门可以装无限量弹药的枪支开始。
- 每回合,玩家将同时从以下动作之一中进行选择:
0
-将1枚弹药装入枪中。1
-向对手发射子弹; 费用为1装弹药。2
-向对手发射等离子束;花费2装弹药。-
-使用金属屏蔽罩防御进来的子弹。=
-使用热偏转器保护入射的等离子体束。
- 如果两个玩家都在第100 个回合后幸存下来,他们都会精疲力竭至死,从而导致平局。
如果玩家失去了对决,
- 难道不使用金属屏蔽捍卫传入的子弹。
- 难道不使用热导流捍卫传入的血浆。
- 在没有装载足够弹药的情况下开枪,在这种情况下他们的枪会自行爆炸并杀死车主。
注意事项
根据《未来枪支拥有者手册》:
- 金属屏蔽CAN NOT从传入等离子体束保卫。同样,热导流板CAN NOT从传入子弹保卫。
- 等离子束压倒了子弹(因为前者需要更多的加载弹药)。因此,如果玩家向在同一回合中发射子弹的对手发射等离子束,则对手会被杀死。
- 如果两个玩家在同一回合向对方发射子弹,则子弹会抵消,并且两个玩家都可以幸存。同样,如果两个玩家都在同一回合中向对方发射等离子束,则两个玩家都将幸免。
还值得注意的是:
- 你会不知道在你的回合中对手的动作,直到结束。
- 偏转等离子束和屏蔽子弹不会伤害您的对手。
因此,每回合共有25个有效的动作组合:
+-------------+---------------------------------------------+
| Outcome | P L A Y E R B |
| Table +--------+-----------------+------------------+
| for Players | Load | Bullet Plasma | Metal Thermal |
+---+---------+--------+--------+--------+--------+---------+
| P | Load | | B wins | B wins | | |
| L +---------+--------+--------+--------+--------+---------+
| A | Bullet | A wins | | B wins | | A wins |
| Y | +--------+--------+--------+--------+---------+
| E | Plasma | A wins | A wins | | A wins | |
| R +---------+--------+--------+--------+--------+---------+
| | Metal | | | B wins | | |
| | +--------+--------+--------+--------+---------+
| A | Thermal | | B wins | | | |
+---+---------+--------+--------+---------------------------+
Note: Blank cells indicate that both players survive to the next turn.
决斗示例
这是我曾经和朋友打过的对决。那时,我们对编程并不了解,因此我们使用手势并以每秒两转的速度发出信号。从左到右,我们的行动依次是:
Me: 001-000-1201101001----2
Friend: 00-10-=1-==--0100-1---1
按照上述规则,我输了。你明白为什么吗?这是因为当我只有1枚弹药时,我发射了最后的等离子束,导致我的枪爆炸。
C ++播放器
你,作为一个文明未来的程序员,也不会直接处理枪支。相反,您编写的代码Player
会与他人抗争。通过在GitHub项目中公开继承c ++类,您可以开始编写城市传奇。
Player.hpp can be found in Tournament\Player.hpp
An example of a derived class can be found in Tournament\CustomPlayer.hpp
你必须或可以做什么
- 您必须
Player
通过公共继承来继承类,并声明您的类为final。 - 您必须重写
Player::fight
,Player::Action
每次调用时都会返回一个有效值。 - (可选)超越
Player::perceive
并Player::declared
留意对手的行动并跟踪您的胜利。 - (可选)在派生类中使用私有静态成员和方法来执行更复杂的计算。
- (可选)使用其他C ++标准库。
你不能做什么
- 你必须不使用任何直接的方法来识别大于给定对手标识符,它在每场比赛的开始洗牌其他对手。您只能通过锦标赛中的玩法来猜测谁是谁。
- 你一定不要覆盖任何方法
Player
未声明的虚拟类。 - 你一定不声明或初始化在全球范围内任何东西。
- 由于(现为不合格)登场
BlackHatPlayer
,玩家不要让其在偷看或修改你的对手的状态。
决斗示例
使用GunDuel
类执行枪决斗的过程。有关打架的示例,请参阅“ 启动决斗”Source.cpp
一节中的。
我们展示GunClubPlayer
,HumanPlayer
以及GunDuel
类,它可以在发现Tournament\
存储库的目录。
在每个决斗中,GunClubPlayer
都会装一颗子弹;开火 冲洗并重复。在每个回合中,HumanPlayer
都会提示您采取行动与对手对抗。你的键盘控制是人物0
,1
,2
,-
和=
。在Windows上,您可以HumanPlayer
用来调试提交。
决斗
这是通过控制台调试播放器的方法。
// Source.cpp
// An example duel between a HumanPlayer and GunClubPlayer.
#include "HumanPlayer.hpp"
#include "GunClubPlayer.hpp"
#include "GunDuel.hpp"
int main()
{
// Total number of turns per duel.
size_t duelLength = 100;
// Player identifier 1: HumanPlayer.
HumanPlayer human(2);
// Player identifier 2: GunClubPlayer.
GunClubPlayer gunClub(1);
// Prepares a duel.
GunDuel duel(human, gunClub, duelLength);
// Start a duel.
duel.fight();
}
游戏范例
您需要击败的回合数最少GunClubPlayer
为3。这是与0-1
对抗时的重放GunClubPlayer
。括号中的数字是回合结束时每个玩家的弹药加载数量。
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [-] defend using metal shield (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: Turn 2
You [0/12/-=] >> [1] fire a bullet (0 ammo)
Opponent selects [0] load ammo (1 ammo)
:: You won after 3 turns!
:: Replay
YOU 0-1
FOE 010
Press any key to continue . . .
GunClubPlayer
不做无效动作而战胜的最快方法是序列0=
,因为子弹正好通过热导板射出。重播是
:: Turn 0
You [0/12/-=] >> [0] load ammo (1 ammo)
Opponent selects [0] load ammo (1 ammo)
:: Turn 1
You [0/12/-=] >> [=] defend using thermal deflector (1 ammo)
Opponent selects [1] fire a bullet (0 ammo)
:: You lost after 2 turns!
:: Replay
YOU 0=
FOE 01
Press any key to continue . . .
比赛
比赛遵循“最后一名选手排名”格式。在锦标赛中,所有有效的提交内容(包括GunClubPlayer
)都放在一个池中。每个提交都分配有一个随机但唯一的标识符,该标识符在整个锦标赛中将保持不变。在每个回合中:
- 每个提交以0分开始,将与其他每个提交进行100决斗。
- 每个胜利的决斗将获得1分;画和输给0分。
- 在该回合结束时,以最低分提交的参赛者将离开比赛。如果出现平局,则自锦标赛开始以来获得积分最少的玩家将离开。
- 如果剩下一名以上的选手,则应开始下一轮比赛。
- 积分不会延续到下一轮。
投稿
您将为每个答案提交一名玩家。您可以为一个播放器提交多个文件,只要它们不干扰其他提交即可。为了保持顺畅,请执行以下操作:
- 将主头文件命名为
<Custom>Player.hpp
, - 将其他文件命名为
<Custom>Player*.*
,例如,MyLittlePlayer.txt
如果您的班级名称为MyLittlePlayer
,或者EmoPlayerHates.cpp
您的班级名称为EmoPlayer
。 - 如果您的姓名包含
Shooter
或符合该比赛背景的类似单词,则无需Player
在末尾添加。如果您强烈认为没有后缀的提交名称会更好Player
,那么您也不需要添加Player
。 - 确保您的代码可以在Windows下编译和链接。
您可以发表评论以要求澄清或发现漏洞。希望您喜欢这款未来派枪决斗,并祝您新年快乐!
澄清度
- 允许您有随机行为。
- 允许执行无效操作(加载弹药不足时触发)。
- 如果玩家输入的内容无效,他们的枪支将立即爆炸。
- 您可以研究答案。
- 明确允许您在每次锦标赛中记录对手的行为。
- 每回合,您将与每个对手进行100次决斗;但是,100个决斗的顺序是随机的-您不能保证连续打相同的对手100个决斗。
其他资源
如果您要提交C ++条目,@ flawr已将提供的C ++源代码翻译成Java作为参考。
非C ++提交的界面
目前已接受:Python 3,Java。
请遵循以下规范之一:
接口规范1:退出代码
您的提交每轮运行一次。
Expected Command Line Argument Format:
<opponent-id> <turn> <status> <ammo> <ammo-opponent> <history> <history-opponent>
Expected Return Code: The ASCII value of a valid action character.
'0' = 48, '1' = 49, '2' = 50, '-' = 45, '=' = 61
<opponent-id> is an integer in [0, N), where N is size of tournament.
<turn> is 0-based.
If duel is in progress, <status> is 3.
If duel is draw / won / lost, <status> is 0 / 1 / 2.
<history> and <history-opponent> are strings of actions, e.g. 002 0-=
If turn is 0, <history> and <history-opponent> are not provided.
You can ignore arguments you don't particularly need.
您可以在PythonPlayer\
和JavaPlayer\
目录中测试提交的内容。
接口规范2:stdin / stdout
(致谢H Walters)
您的提交将在每个锦标赛中运行一次。
由于stdin和stdout均已连接到锦标赛驱动程序,因此对如何执行I / O的所有条目都有固定的要求。违反此规定可能导致死锁。所有条目都必须遵循此EXACT算法(以伪代码):
LOOP FOREVER
READ LINE INTO L
IF (LEFT(L,1) == 'I')
INITIALIZE ROUND
// i.e., set your/opponent ammo to 0, if tracking them
// Note: The entire line at this point is a unique id per opponent;
// optionally track this as well.
CONTINUE LOOP
ELSE IF (LEFT(L,1) == 'F')
WRITELN F // where F is your move
ELSE IF (LEFT(L,1) == 'P')
PROCESS MID(L,2,1) // optionally perceive your opponent's action.
END IF
CONTINUE LOOP
QUIT
这里,F是一0
,1
,2
,-
,或者=
为load / bullet / plasma / metal / thermal
。PROCESS意味着有选择地对对手的反应做出反应(如果您这样做的话,包括跟踪对手的弹药)。请注意,对手的动作也是“ 0”,“ 1”,“ 2”,“-”或“ =”之一,并且处于第二个字符中。
最终比分板
08:02 AM Tuesday, February 2, 2017 Coordinated Universal Time (UTC)
| Player | Language | Points | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
|:------------------ |:---------- | ------:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:| -----:|
| MontePlayer | C++ | 11413 | 1415 | 1326 | 1247 | 1106 | 1049 | 942 | 845 | 754 | 685 | 555 | 482 | 381 | 287 | 163 | 115 | 61 |
| CBetaPlayer | C++ | 7014 | 855 | 755 | 706 | 683 | 611 | 593 | 513 | 470 | 414 | 371 | 309 | 251 | 192 | 143 | 109 | 39 |
| StudiousPlayer | C++ | 10014 | 1324 | 1233 | 1125 | 1015 | 907 | 843 | 763 | 635 | 555 | 478 | 403 | 300 | 201 | 156 | 76 |
| FatedPlayer | C++ | 6222 | 745 | 683 | 621 | 655 | 605 | 508 | 494 | 456 | 395 | 317 | 241 | 197 | 167 | 138 |
| HanSoloPlayer | C++ | 5524 | 748 | 668 | 584 | 523 | 490 | 477 | 455 | 403 | 335 | 293 | 209 | 186 | 153 |
| SurvivorPlayer | C++ | 5384 | 769 | 790 | 667 | 574 | 465 | 402 | 354 | 338 | 294 | 290 | 256 | 185 |
| SpecificPlayer | C++ | 5316 | 845 | 752 | 669 | 559 | 488 | 427 | 387 | 386 | 340 | 263 | 200 |
| DeceptivePlayer | C++ | 4187 | 559 | 445 | 464 | 474 | 462 | 442 | 438 | 369 | 301 | 233 |
| NotSoPatientPlayer | C++ | 5105 | 931 | 832 | 742 | 626 | 515 | 469 | 352 | 357 | 281 |
| BarricadePlayer | C++ | 4171 | 661 | 677 | 614 | 567 | 527 | 415 | 378 | 332 |
| BotRobotPlayer | C++ | 3381 | 607 | 510 | 523 | 499 | 496 | 425 | 321 |
| SadisticShooter | C++ | 3826 | 905 | 780 | 686 | 590 | 475 | 390 |
| TurtlePlayer | C++ | 3047 | 754 | 722 | 608 | 539 | 424 |
| CamtoPlayer | C++ | 2308 | 725 | 641 | 537 | 405 |
| OpportunistPlayer | C++ | 1173 | 426 | 420 | 327 |
| GunClubPlayer | C++ | 888 | 500 | 388 |
| PlasmaPlayer | C++ | 399 | 399 |
除非另有说明,否则比赛将持续到2017年2月1日。
Player
调用另一个过程来计算当前转弯的实现。这样一来,人们就可以使用您乐于在计算机上运行的任何语言进行参与。
Player::fight
” /“您可以继承Player::perceive
” ...在两种情况下,该术语都是重写,不是继承。
GunDuel.hpp
,都validA
与validB
使用actionA