Created
July 15, 2023 22:00
-
-
Save gregomni/5a82662cff008a212a3dcd7ba2bf7564 to your computer and use it in GitHub Desktop.
Banana-only Scrabble, naive and slow (for now)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// main.swift | |
// banana | |
// | |
// Created by Greg Titus on 7/15/23. | |
// | |
import Foundation | |
enum Letter: Character, Hashable { | |
case empty = "." | |
case b = "B" | |
case a = "A" | |
case n = "N" | |
static let banana: [Letter] = [.b, .a, .n, .a, .n, .a] | |
} | |
struct Position { | |
let row: Int | |
let column: Int | |
var up: Position { Position(row: row-1, column: column) } | |
var down: Position { Position(row: row+1, column: column) } | |
var left: Position { Position(row: row, column: column-1) } | |
var right: Position { Position(row: row, column: column+1) } | |
} | |
struct Board: Hashable { | |
static let size = 15 | |
var array: [Letter] | |
init() { | |
self.array = Array(repeating: .empty, count: Self.size * Self.size) | |
} | |
subscript(_ p: Position) -> Letter { | |
get { array[p.row * Self.size + p.column] } | |
set { array[p.row * Self.size + p.column] = newValue } | |
} | |
mutating func addBanana(_ p: Position, vertical: Bool) { | |
var p = p | |
for tile in Letter.banana { | |
self[p] = tile | |
p = vertical ? p.down : p.right | |
} | |
} | |
func byAdding(_ p: Position, vertical: Bool) -> Board { | |
var result = self | |
result.addBanana(p, vertical: vertical) | |
return result | |
} | |
func canAddBanana(_ at: Position, vertical: Bool, index: Int) -> Bool { | |
guard self[at] == Letter.banana[index] else { return false } | |
var laidTile = false | |
if vertical { | |
guard at.row - index >= 0 else { return false } | |
guard at.row + (5-index) < Board.size else { return false} | |
var p = Position(row: at.row - index, column: at.column) | |
guard p.row == 0 || self[p.up] == .empty else { return false } | |
for tile in Letter.banana { | |
if self[p] == tile { | |
} else if self[p] == .empty { | |
if p.column > 0 && self[p.left] != .empty { return false } | |
if p.column < 14 && self[p.right] != .empty { return false } | |
laidTile = true | |
} else { | |
return false | |
} | |
p = p.down | |
} | |
guard p.row == 15 || self[p] == .empty else { return false } | |
} else { | |
guard at.column - index >= 0 else { return false } | |
guard at.column + (5-index) < Board.size else { return false} | |
var p = Position(row: at.row, column: at.column - index) | |
guard p.column == 0 || self[p.left] == .empty else { return false } | |
for tile in Letter.banana { | |
if self[p] == tile { | |
} else if self[p] == .empty { | |
if p.row > 0 && self[p.up] != .empty { return false } | |
if p.row < 14 && self[p.down] != .empty { return false } | |
laidTile = true | |
} else { | |
return false | |
} | |
p = p.right | |
} | |
guard p.column == 15 || self[p] == .empty else { return false } | |
} | |
return laidTile | |
} | |
func nextMoves(vertical: Bool) -> [Board] { | |
var result: [Board] = [] | |
func addIfPossible(_ p: Position, vertical: Bool, index: Int) { | |
if canAddBanana(p, vertical: vertical, index: index) { | |
let p = vertical ? Position(row: p.row-index, column: p.column) : Position(row: p.row, column: p.column-index) | |
result.append(self.byAdding(p, vertical: vertical)) | |
} | |
} | |
for row in 0..<15 { | |
for column in 0..<15 { | |
let p = Position(row: row, column: column) | |
switch self[p] { | |
case .b: | |
addIfPossible(p, vertical: vertical, index: 0) | |
case .a: | |
addIfPossible(p, vertical: vertical, index: 1) | |
addIfPossible(p, vertical: vertical, index: 3) | |
addIfPossible(p, vertical: vertical, index: 5) | |
case .n: | |
addIfPossible(p, vertical: vertical, index: 2) | |
addIfPossible(p, vertical: vertical, index: 4) | |
case .empty: | |
break | |
} | |
} | |
} | |
return result | |
} | |
func nextMoves() -> [Board] { | |
return nextMoves(vertical: true) + nextMoves(vertical: false) | |
} | |
func description() -> String { | |
var result = "" | |
for row in 0..<15 { | |
for column in 0..<15 { | |
result.append(self[Position(row: row, column: column)].rawValue) | |
} | |
result.append("\n") | |
} | |
return result | |
} | |
} | |
var start = Board() | |
start.addBanana(Position(row: 7, column: 7), vertical: false) | |
var possibilities: [Set<Board>] = [] | |
possibilities.append([start]) | |
print("move 1: \(possibilities[0].count) moves") | |
for move in 1..<16 { | |
var new = Set<Board>() | |
for board in possibilities[move-1] { | |
new.formUnion(board.nextMoves()) | |
} | |
possibilities.append(new) | |
print("move \(move+1): \(possibilities[move].count) moves") | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment