Skip to content

Instantly share code, notes, and snippets.

@Ryan-M-Smith
Last active November 15, 2020 21:54
Show Gist options
  • Save Ryan-M-Smith/fd3ac15b81364f0e25ca74dc6880d026 to your computer and use it in GitHub Desktop.
Save Ryan-M-Smith/fd3ac15b81364f0e25ca74dc6880d026 to your computer and use it in GitHub Desktop.
A Swift command line program to test if a queen on a chess board at a certain location could capture a piece at another location
//
// FILENAME: canCapture.Swift
// DESCRIPTION: A program that test if a queen on a chess board at a certain
// location could capture a piece at another location.
// COPYRIGHT: Copyright (c) 2020 by Ryan Smith
//
import Swift
func makePair(coords: String, fromKey key: [Character: Int]) -> (x: Int?, y: Int?) {
// Make a chess board location (like "A1") into an ordered pair (like (1, 1)).
var x = Int(), y: Int
// Convert the letter in the coordinate to a number from the
// key
for letter in key.keys {
if coords.contains(letter) {
x = key[letter]!
}
}
// Convert the paired number (`String`) to `Int`
let num = coords[coords.index(coords.startIndex, offsetBy: 1)]
y = Int(String(num))!
// Root out invalid board indices by making sure the letter and
// number are both valid.
guard (x != Int()) && (1...8 ~= y) else {
return (nil, nil)
}
return (x, y)
}
func comparePoints(_ coordGroup: [(x: Int, y: Int)]) -> Bool {
// Compare the two points, and see if the queen can capture. Returns `true`
// if a capture is possible, `false` otherwise. This return value is returned
// from `canCapture()`, but the functionality is in this here to avoid clutter
// in `canCapture()`.
// First, make the array of points into two tuples. `first` and `last`
// are used in the two-element list instead of coordGroup[0]/[1] to
// improve readability
//
// Queen Location: (x1, y1) -> (qR, qC)
// Opponent Location: (x2, y2) -> (oR, oC)
let (qR, qC) = (coordGroup.first!.x, coordGroup.first!.y)
let (oR, oC) = (coordGroup.last!.x, coordGroup.last!.y)
// Determine if a capture is possible
if (qR == oR) || (qC == oC) || (abs(qR - oR) == abs(qC - oC)) {
return true
}
else {
return false
}
}
func canCapture(_ pieces: [String]) -> Bool {
if pieces.count != 2 {
return false
}
// A key to convert a character to an integer. This is
// used to make ordered pairs out of chess board locations.
let letterDict: [Character: Int] = [
"A": 1,
"B": 2,
"C": 3,
"D": 4,
"E": 5,
"F": 6,
"G": 7,
"H": 8
]
// In this case, the array will only ever have two items, so `pieces.last` can be used
// instead of `pieces[1]`.
let (x1, y1) = makePair(coords: pieces.first!, fromKey: letterDict)
let (x2, y2) = makePair(coords: pieces.last!, fromKey: letterDict)
if (x1 != nil) && (y1 != nil) && (x2 != nil) && (y2 != nil) {
return comparePoints([(x1!, y1!), (x2!, y2!)])
}
else {
return false
}
}
// A few example uses
print(canCapture(["H1", "A2"])) // `false`
print(canCapture(["A5", "D8"])) // `true`
print(canCapture(["K5", "D8"])) // `false`; invalid queen index
print(canCapture(["C4", "E6", "F3"])) // `false`; too many arguments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment