Quadrant.groovy
package net.ebdon.trk21;
/**
* @file
* @author Terry Ebdon
* @date January 2019
* @copyright
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@groovy.util.logging.Log4j2
final class Quadrant extends GameSpace {
enum Thing {
emptySpace( '.' ),
ship( 'E' ),
enemy( 'K' ),
base( 'B' ),
star( '*' )
final char symbol;
Thing( sym ) { symbol = sym }
}
int getCellPadding() {
1
}
String symbol( final key ) {
// println "get key: $key"
// log.debug "get key: $key"
board.get( key ).symbol
}
boolean isOccupied( i, j ) {
board[i,j] != Thing.emptySpace
}
final Thing getAt( key ) {
board.get key
}
final def putAt( key, Thing value ) {
board[key] = value
}
final def putAt( final Coords2d coords, Thing value ) {
board[coords.row,coords.col] = value
}
final void clearSquare( final row, final col ) {
board[row,col] = Thing.emptySpace //.ordinal()
}
/// @bug Infinite loop is possible.
/// @todo add a time-out.
def getEmptySector() {
int r1
int r2
(r1,r2) = getRandomCoords()
log.trace "getEmptySector() starts with r1:$r1, r2:$r2 = ${board[r1,r2]} board size is ${board.size()}"
while ( isOccupied(r1,r2) ) {
(r1,r2) = getRandomCoords()
log.trace "Is ${[r1,r2]} empty?"
}
log.trace "getEmptySector() ends with r1:$r1, r2:$r2 = ${board[r1,r2]}"
[r1,r2]
}
/**
Output the sectors of the current quadrant, showing the position of all game
objects present. This is the top-half of the display generated by
Trek.shortRangeScan(). It's also used for logging in Trek.positionEnemy()
during the sector setup.
@arg linePrinter - A closure that will be called to output each line of the
sector display.
*/
def displayOn( Closure linePrinter ) {
1.upto(8) { i ->
String scanLine = ''
1.upto(8) { j ->
scanLine += "${symbol([i,j])} "
}
linePrinter( scanLine )
}
}
def findEnemies() {
board.findAll { it.value == Thing.enemy }
}
def removeEnemy( key ) {
assert board[key] == Thing.enemy
board[key] = Thing.emptySpace
}
int count( Closure closure ) {
board.count closure
}
}