-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPlayer.java
More file actions
128 lines (110 loc) · 3.65 KB
/
Player.java
File metadata and controls
128 lines (110 loc) · 3.65 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package snake.controller;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import snake.model.BodyPart;
import snake.model.Direction;
import snake.model.Field;
import snake.model.Field.Terrain;
import snake.model.Snake;
/**
* @author afeher
*/
public class Player {
private Snake snake;
private boolean alive;
public Player() {
snake = new Snake();
snake.append(3);
alive = true;
}
public Field[][] introduce(Field[][] court) {
Field[][] snapshot = snapshot(court);
dropFood(snapshot);
updateTerrainOccupied(snapshot, snake);
return snapshot;
}
public Field[][] tick(Field[][] court, Direction direction) {
Field[][] snapshot = snapshot(court);
Snake beforeMove = snake.copy();
Terrain terrain = move(snapshot, direction);
switch(terrain) {
case FOOD: eat(); dropFood(snapshot); break;
case SNAKE: break;
case OFF_GRID: die(); return snapshot;
case PLAIN: // nothing to do
default:
}
updateTerrainLeft(snapshot, beforeMove);
updateTerrainOccupied(snapshot, snake);
return snapshot;
}
private Terrain move(Field[][] court, Direction direction) {
snake.move(direction);
BodyPart head = snake.getHead();
if (court.length <= head.getX()
|| court[0].length <= head.getY()
|| head.getY() < 0
|| head.getX() < 0) {
return Terrain.OFF_GRID;
} else {
return getField(court, head).getTerrain();
}
}
private Field getField(Field[][] court, BodyPart bodyPart) {
return court[bodyPart.getX()][bodyPart.getY()];
}
private void updateTerrainLeft(Field[][] court, Snake beforeMove) {
for (BodyPart bodyPart : beforeMove.getBody()) {
getField(court, bodyPart).setTerrain(Terrain.PLAIN);
}
}
private void updateTerrainOccupied(Field[][] court, Snake afterMove) {
for (BodyPart bodyPart : afterMove.getBody()) {
getField(court, bodyPart).setTerrain(Terrain.SNAKE);
}
}
private Field[][] snapshot(Field[][] court) {
Field[][] snapshot = new Field[court.length][court[0].length];
for (int y = 0; y < court.length; y++) {
for (int x = 0; x < court[0].length; x++) {
snapshot[y][x] = court[y][x].copy();
}
}
return snapshot;
}
private void eat() {
snake.append(1);
}
private void dropFood(Field[][] court) {
List<Field> available = getAvailableFields(court);
List<Field> occupied = getOccupiedFields(snake);
available.removeAll(occupied);
Collections.shuffle(available);
int random = new Random().nextInt(available.size());
Field choosen = available.get(random);
court[choosen.getX()][choosen.getY()].setTerrain(Field.Terrain.FOOD);
}
private List<Field> getAvailableFields(Field[][] court) {
List<Field> available = new ArrayList<>();
for (Field[] fields : court) {
available.addAll(Arrays.asList(fields));
}
return available;
}
private List<Field> getOccupiedFields(Snake snake) {
List<Field> occupied = new ArrayList<>();
for (BodyPart part : snake.getBody()) {
occupied.add(new Field(part.getX(), part.getY()));
}
return occupied;
}
private void die() {
alive = false;
}
public boolean isAlive() {
return alive;
}
}