贪吃蛇玩法

操作规则

与传统单人贪吃蛇不同的是,本贪吃蛇为双人对战,每回合玩家同时做出决策控制自己的蛇。

玩家在$13\times 14$的网格中操纵一条蛇(蛇是一系列坐标构成的有限不重复有顺序的序列,序列中相邻坐标均相邻,即两坐标的$x$轴坐

标或$y$轴坐标相同,序列中第一个坐标代表蛇头),玩家只能控制蛇头的朝向(东、南、西和北)来控制蛇。

玩家通过键盘中的 WASD 或者、控制蛇的移动

每名玩家都有5秒的时间来考虑下一步操作,如果超出时间没有进行输入,系统就会自动判

与传统贪吃蛇不同,本游戏在网格中并没有豆子,但蛇会自动长大(长大即为不删除序列末尾坐标的前进),前$10$回合每回合长度

$1$,从第$11$回合开始,每$3$回合长度增加$1$。

地图为$13\times 14$的网格,由$1\times 1$的草地与障碍物构成。

蛇头在网格外、障碍物、自己蛇的身体(即序列重复)、对方蛇的身体(即与对方序列有相同坐标),或非法操作均判定为死亡。任何

一条蛇死亡时,游戏结束。若蛇同时死亡,判定为平局,否则先死的一方输,另一方赢。

Bot代码样例说明

在Bot代码中,用户需要返回[0,1,2,3]中的一个数字,方向分别为

用户只需要编写nextMove这一个核心函数即可,其余函数为平台提供的辅助代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package com.kob.botrunningsystem.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Bot implements java.util.function.Supplier<Integer> {
// 地图 # me.sx # me.sy #( 我的操作序列 )# you.sx # you.sy #( 你的操作序列 )
// 由于操作序列可能为空 故加()
// 0表示上,1表示左,2表示下,3表示右

static class Cell {
public int x, y;
public Cell(int x, int y) { // 蛇身体的某一个部位的坐标
this.x = x;
this.y = y;
}
}

private boolean check_tail_increasing(int step) { // 检验当前回合蛇是否会变长
if(step <= 10) return true;
return step % 3 == 1;
}

public List<Cell> getCells(int sx, int sy, String steps) { // 得到蛇身体所有部位的坐标
steps = steps.substring(1, steps.length() - 1); // 去除()
List<Cell> res = new ArrayList<>();

int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
int x = sx, y = sy;
int step = 0;
res.add(new Cell(x, y));
for(int i = 0; i < steps.length(); i ++ ) {
int d = steps.charAt(i) - '0';
x += dx[d];
y += dy[d];
res.add(new Cell(x, y));
if(!check_tail_increasing( ++ step)) {
res.remove(0);
}
}
return res;
}

// 用户需要编写的核心函数,返回一个[0,1,2,3]中的数字
public Integer nextMove(String input) {
String[] strs = input.split("#");
int[][] g = new int[13][14]; // 定义地图
for (int i = 0, k = 0; i < 13; i++) {
for (int j = 0; j < 14; j++, k++) {
if (strs[0].charAt(k) == '1') {
g[i][j] = 1;
}
}
}

int aSx = Integer.parseInt(strs[1]), aSy = Integer.parseInt(strs[2]);
int bSx = Integer.parseInt(strs[4]), bSy = Integer.parseInt(strs[5]);

List<Cell> aCells = getCells(aSx, aSy, strs[3]);
List<Cell> bCells = getCells(bSx, bSy, strs[6]);

for(Cell c: aCells) g[c.x][c.y] = 1;
for(Cell c: bCells) g[c.x][c.y] = 1;

int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
for(int i = 0; i < 4; i ++ ) {
int x = aCells.get(aCells.size() - 1).x + dx[i];
int y = aCells.get(aCells.size() - 1).y + dy[i];
if(x >= 0 && x < 13 && y >= 0 && y < 14 && g[x][y] == 0) {
return i;
}
}

return 0; // 判断都成功,就随便走
}

// 入口函数
@Override
public Integer get() {
File file = new File("input.txt");
try {
Scanner sc = new Scanner(file);
return nextMove(sc.next());
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}