Wankan

Untitled

Aug 30th, 2020 (edited)
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 3.96 KB | None | 0 0
  1. import external "readline" as readline
  2.  
  3. class ReadlineInterface with ():
  4.     this.input = process.stdin
  5.     this.output = process.stdout
  6.  
  7. rlInterface = ReadlineInterface $ ()
  8. rl = readline.createInterface rlInterface
  9.  
  10. class Game with ():
  11.     this.CurrentPlayer = 1
  12.     this.N = 2
  13.     this.MoveCount = 0
  14.     this.Won = 0
  15.  
  16.     # Num -> Map<0> Num
  17.     this.generateBoard = with size do:
  18.         row = (_ => 0) <$> [0..size]'1
  19.        cols = (_=> @(copy row)) <$> [0..size]'1
  20.         return cols'0
  21.  
  22.    this.Board = this.generateBoard this.N
  23.  
  24.    # Num -> Num -> Num -> ()
  25.    this.Move = with (x, y, playerSign) do:
  26.        currentVal = (this.Board)[x][y]
  27.        newVal = currentVal == 0 ? playerSign : currentVal
  28.  
  29.        # List -> List
  30.        updateBoard = board => board.set [x, y] newVal
  31.        this.Board = updateBoard <$> this.Board
  32.        this.MoveCount += 1
  33.  
  34.        winner = (this.HorizontalCheck x playerSign) || (this.VerticalCheck y playerSign) || (this.DiagonalCheck playerSign)
  35.        this.Won = winner ? playerSign : 0
  36.  
  37.    # Num -> Num -> Bool
  38.    this.HorizontalCheck = (x, sign) => this.Board[x] \& (v => v == sign)
  39.    this.VerticalCheck = (y, sign) => this.Board'1[y] \& (v => v == sign)
  40.  
  41.     # List -> A -> Bool
  42.     this.allEquals = (list, value) => list'0 \& (x => x == value)
  43.    # Num -> Bool
  44.    this.DiagonalCheck = with sign do:
  45.        b = this.Board
  46.        TL_BR_Diag = this.allEquals [b[0][0], b[1][1], b[2][2]] sign
  47.        BL_TR_Diag = this.allEquals [b[2][0], b[1][1], b[0][2]] sign
  48.        return TL_BR_Diag || BL_TR_Diag
  49.  
  50.    # String -> List<String> -> Map<1> List<String> -> Map<0> List<String>
  51.    this.ParseInputs = {
  52.        rawInput => List (rawInput.split " ")
  53.        args => (x => parseInt x) <$> args'1
  54.         highMap => highMap'0
  55.    }
  56.  
  57.    # Num -> String
  58.    # Num[] -> String
  59.    this.stateToString = state => state == 0 ? " " : state == 1 ? "X" : "O"
  60.    this.rowToString = row => @(this.stateToString <$> row'1).join " │ "
  61.     # () -> String
  62.     this.Display = with () do:
  63.         rows = this.rowToString <$> this.Board'1
  64.        log <- "\n" + (@rows.join "\n──┼───┼──\n") + "\n"
  65.  
  66.    # Map<0> List<String> -> Maybe<Map<0> List<String>>
  67.    this.checkInput = with input do:
  68.        if @input.length != 2:
  69.            return Nothing
  70.        
  71.        if input \| (n => isNaN n):
  72.            return Nothing
  73.  
  74.        # Num -> BBool
  75.        outOfBounds = x => x < 0 || 2 < x
  76.        if (outOfBounds input[0]) || (outOfBounds input[1]):
  77.            return Nothing
  78.  
  79.        return Just input
  80.  
  81.    # () -> String
  82.    this.Start = with () do:
  83.        this.Display ()
  84.        log <- "Player X's turn:"
  85.  
  86.    # () -> String
  87.    this.DisplayWinner = with () do:
  88.        log <- "Player " + (this.stateToString this.Won) + " has won"
  89.  
  90.    # String -> ()
  91.    this.Input = with inputString do:
  92.        m_tileIndex = (Try (_ => inputString ~ this.ParseInputs)) >>= this.checkInput
  93.  
  94.        if m_tileIndex =: CMaybeJust:
  95.            tileIndex = @m_tileIndex
  96.            this.Move tileIndex[0] tileIndex[1] this.CurrentPlayer
  97.  
  98.            this.CurrentPlayer = this.CurrentPlayer == 1 ? 2 : 1
  99.            this.Display()
  100.  
  101.            if this.Won != 0:
  102.                this.DisplayWinner ()
  103.            elif this.MoveCount == 9:
  104.                log <- "This game has ended in a draw"
  105.                this.Won = (-1)
  106.            else:
  107.                log <- "Player " + (this.stateToString this.CurrentPlayer) + "'s turn:"            
  108.        else:
  109.            log <- "Invalid input: '" + inputString + "', try again"
  110.            log <- "Player " + (this.stateToString this.CurrentPlayer) + "'s turn:"
  111.  
  112.  
  113. game = Game $ ()
  114. game.Start ()
  115.  
  116. # String -> ()
  117. handleAnswer = with answer do:
  118.    game.Input answer
  119.  
  120.    if game.Won != 0:
  121.        rl.close ()
  122.    else:
  123.        turn ()
  124.  
  125. # () -> ()
  126. turn = with () do:
  127.    rl.question "> " handleAnswer
  128.  
  129. turn ()
  130.  
Add Comment
Please, Sign In to add comment