Skip to content

Instantly share code, notes, and snippets.

@bipin-a
Created April 20, 2020 03:51
Show Gist options
  • Save bipin-a/a5b60f8125d0344bc8a48cd353f5c220 to your computer and use it in GitHub Desktop.
Save bipin-a/a5b60f8125d0344bc8a48cd353f5c220 to your computer and use it in GitHub Desktop.
Created on Skills Network Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import Foundation\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"struct TicTacToe{\n",
" var board: [[Int]]\n",
"}\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" init (){\n",
" self.init(board: [[Int]](repeating: [Int](repeating: 0, count: 3), count: 3))\n",
" }\n",
"} "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" func isWin (for player:Int) -> Bool {\n",
" let wanting = [player, player, player]\n",
" for i in board {\n",
" if i == wanting {\n",
" return true\n",
" }\n",
" }\n",
" \n",
" for col in 0..<3{\n",
" let row = [board[0][col], board[1][col], board[2][col]]\n",
" if row == wanting { \n",
" return true\n",
" }\n",
" }\n",
" \n",
" let diag1 = [board[0][0], board[1][1], board[2][2]]\n",
" if diag1 == wanting { \n",
" return true\n",
" }\n",
" \n",
" let diag2 = [board[0][2], board[1][1], board[2][0]]\n",
" if diag2 == wanting { \n",
" return true\n",
" }\n",
" return false\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" var legalMoves : [(Int,Int)] {\n",
" var legals: [(Int,Int)] = []\n",
" for row in 0..<3 {\n",
" for col in 0..<3 {\n",
" if board[row][col] == 0 {\n",
" legals.append((row,col)) // Moves available\n",
" }\n",
" }\n",
" }\n",
" return legals\n",
" }\n",
" \n",
" var hasWinner: Bool {\n",
" return isWin(for: 1) || isWin(for: -1)\n",
" }\n",
" \n",
" var isOver: Bool {\n",
" return hasWinner || legalMoves.isEmpty\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" mutating func play(at location: (Int, Int), player: Int) {\n",
" guard board[location.0][location.1] == 0 else {\n",
" fatalError()\n",
" }\n",
" board[location.0][location.1] = player\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" func children (player: Int) -> [TicTacToe] {\n",
" var nextMoves: [TicTacToe] = []\n",
" for i in legalMoves {\n",
" var copy = TicTacToe(board: board)\n",
" copy.play(at: i, player: player)\n",
" nextMoves.append(copy)\n",
" }\n",
" return nextMoves\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" func winner(depth: Int) -> Int {\n",
" if isWin(for: 1) {\n",
" return 10 - depth\n",
" }\n",
" if isWin(for: -1) {\n",
" return depth - 10\n",
" }\n",
" return 0\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"extension TicTacToe {\n",
" // Translates numbers to players. 0 : \" \", 1: \"x\", -1: \"o\"\n",
" static func character(_ x: Int) -> String {\n",
" x == 0 ? \" \" : (x == 1 ? \"x\" : \"o\")\n",
" }\n",
" \n",
" func display() {\n",
" var boardTemplate = \"\"\"\n",
" +-+-+-+\n",
" |1|2|3|\n",
" +-+-+-+\n",
" |4|5|6|\n",
" +-+-+-+\n",
" |7|8|9|\n",
" +-+-+-+\n",
" \"\"\" \n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"1\", with: \"\\(TicTacToe.character(board[0][0]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"2\", with: \"\\(TicTacToe.character(board[0][1]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"3\", with: \"\\(TicTacToe.character(board[0][2]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"4\", with: \"\\(TicTacToe.character(board[1][0]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"5\", with: \"\\(TicTacToe.character(board[1][1]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"6\", with: \"\\(TicTacToe.character(board[1][2]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"7\", with: \"\\(TicTacToe.character(board[2][0]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"8\", with: \"\\(TicTacToe.character(board[2][1]))\")\n",
" boardTemplate = boardTemplate.replacingOccurrences(of: \"9\", with: \"\\(TicTacToe.character(board[2][2]))\")\n",
" print(boardTemplate, terminator: \"\\n\\n\")\n",
"\n",
" }\n",
" \n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"func minimax(state: TicTacToe, player: Int, depth: Int = 0) -> Double {\n",
" if state.isOver {\n",
" return Double(state.winner (depth: depth))\n",
" }\n",
" \n",
" let children = state.children(player: player)\n",
" .map({minimax(state: $0, player: -player, depth: depth + 1) })\n",
" if player == 1 {\n",
" return children.max()!\n",
" } else {\n",
" return children.min()!\n",
" }\n",
" \n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"func decision(for state: TicTacToe, player: Int) -> (Int, Int) {\n",
" let children = state.children(player: player)\n",
" let scores = children.map({Double(player) * minimax(state: $0, player: -player) })\n",
" return state.legalMoves[scores.firstIndex(where:{ $0 == scores.max()! })!]\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x| | |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x| | |\n",
" +-+-+-+\n",
" | |o| |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x| |\n",
" +-+-+-+\n",
" | |o| |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" | |o| |\n",
" +-+-+-+\n",
" | | | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" | |o| |\n",
" +-+-+-+\n",
" |x| | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" |o|o| |\n",
" +-+-+-+\n",
" |x| | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" |o|o|x|\n",
" +-+-+-+\n",
" |x| | |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" |o|o|x|\n",
" +-+-+-+\n",
" |x|o| |\n",
" +-+-+-+\n",
"\n",
" +-+-+-+\n",
" |x|x|o|\n",
" +-+-+-+\n",
" |o|o|x|\n",
" +-+-+-+\n",
" |x|o|x|\n",
" +-+-+-+\n",
"\n"
]
}
],
"source": [
"var state = TicTacToe()\n",
"var player = 1\n",
"state.display()\n",
"while !state.isOver {\n",
" state.play(at: decision(for: state, player: player), player: player)\n",
" player = -player\n",
" state.display()\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"ename": "",
"evalue": "",
"execution_count": 31,
"output_type": "error",
"status": "error",
"traceback": [
"error: <Cell 31>:1:1: error: use of unresolved identifier 'winner'\nwinner\n^~~~~~\n\n"
]
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Swift",
"language": "swift",
"name": "conda-env-swift-swift"
},
"language_info": {
"file_extension": ".swift",
"mimetype": "text/x-swift",
"name": "swift",
"version": ""
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment