aboutsummaryrefslogtreecommitdiff
path: root/src/ch/epfl/xblast/server/Board.java
blob: 06f30814a1035ebe1ffa09808ffbdb74d41eeba9 (plain)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package ch.epfl.xblast.server;

import ch.epfl.cs108.Sq;
import ch.epfl.xblast.Cell;
import ch.epfl.xblast.Lists;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * A two-dimensional Board in which the game takes place.
 *
 * @author Pacien TRAN-GIRARD (261948)
 * @author Timothée FLOURE (257420)
 */
public final class Board {

    /**
     * Distance (in SubCells) from a bomb to block a player.
     */
    static final int BOMB_BLOCKING_DISTANCE = 6;

    private static final int BLOCKS_LIST_SIZE = 195;
    private static final int BOARD_ROWS = 13;
    private static final int BOARD_COLUMNS = 15;
    private static final int INNER_BOARD_ROWS = BOARD_ROWS - 2;
    private static final int INNER_BOARD_COLUMNS = BOARD_COLUMNS - 2;
    private static final int QUADRANT_ROWS = 6;
    private static final int QUADRANT_COLUMNS = 7;
    /**
     * List containing all the blocks of the board.
     */
    private List<Sq<Block>> blocks;

    /**
     * Instantiates a new Board with the given sequence of blocks.
     *
     * @param blocks sequence containing all the blocks of the Boards
     * @throws IllegalArgumentException if the blocks is not composed of BLOC_LIST_SIZE elements
     */
    public Board(List<Sq<Block>> blocks) {
        if (blocks == null || blocks.size() != BLOCKS_LIST_SIZE)
            throw new IllegalArgumentException();

        this.blocks = new ArrayList<>(blocks);
    }

    /**
     * Build a symmetric walled board from the NWB quadrant.
     *
     * @param quadrantNWBlocks the NW quadrant of the board (inner blocks only!)
     * @return a new walled board symmetrically filled with the given NW quadrant
     * @throws IllegalArgumentException if quadrantNWBlocks is not QUADRANT_ROWS * QUADRANT_COLUMNS
     */
    public static Board ofQuadrantNWBlocksWalled(List<List<Block>> quadrantNWBlocks) {
        Board.checkBlockMatrix(quadrantNWBlocks, QUADRANT_ROWS, QUADRANT_COLUMNS);

        List<List<Block>> innerRows = Lists.mirrored(quadrantNWBlocks.stream()
                .map(Lists::mirrored)
                .collect(Collectors.toList()));

        return Board.ofInnerBlocksWalled(innerRows);
    }

    /**
     * Throw an exception if the matrix does not have the given number of rows/columns.
     *
     * @param matrix  the tested matrix
     * @param rows    the expected number of rows
     * @param columns the expected number of columns
     * @throws IllegalArgumentException if the matrix does not comply with the given sizes.
     */
    private static void checkBlockMatrix(List<List<Block>> matrix, int rows, int columns) {
        if (matrix == null || matrix.size() != rows)
            throw new IllegalArgumentException();

        for (List<Block> row : matrix)
            if (row.size() != columns)
                throw new IllegalArgumentException();
    }

    /**
     * Build a walled board filled with the given inner rows
     *
     * @param innerBlocks lists of the internal rows
     * @return a new walled board filled with the given rows
     * @throws IllegalArgumentException if innerBlocks is not INNER_BOARD_ROWS * INNER_BOARD_COLUMNS
     */
    public static Board ofInnerBlocksWalled(List<List<Block>> innerBlocks) {
        Board.checkBlockMatrix(innerBlocks, INNER_BOARD_ROWS, INNER_BOARD_COLUMNS);

        List<List<Block>> innerRows = innerBlocks.stream()
                .map(r -> Lists.surrounded(r, Block.INDESTRUCTIBLE_WALL))
                .collect(Collectors.toList());

        List<List<Block>> completeMatrix = Lists.surrounded(
                innerRows, Collections.nCopies(BOARD_COLUMNS, Block.INDESTRUCTIBLE_WALL));

        return Board.ofRows(completeMatrix);
    }

    /**
     * Build a new Board with the given Matrix.
     *
     * @param rows list containing all the rows
     * @return a new Board built with given rows
     * @throws IllegalArgumentException if rows is not BOARD_ROWS * BOARD_COLUMNS
     */
    public static Board ofRows(List<List<Block>> rows) {
        Board.checkBlockMatrix(rows, BOARD_ROWS, BOARD_COLUMNS);

        List<Sq<Block>> blockSequence = rows.stream()
                .flatMap(Collection::stream)
                .map(Sq::constant)
                .collect(Collectors.toList());

        return new Board(blockSequence);
    }

    /**
     * Returns the block related to the given cell.
     *
     * @param c cell
     * @return the first block of the sequence related to the given cell
     */
    public Block blockAt(Cell c) {
        return this.blocksAt(c).head();
    }

    /**
     * Return the sequence of blocks related to the given cell.
     *
     * @param c cell
     * @return the sequence of blocks related to the given cell.
     */
    public Sq<Block> blocksAt(Cell c) {
        return this.blocks.get(c.rowMajorIndex());
    }

}