DEV Community

Cover image for Use Nim language to implement Nim Game
ringabout
ringabout

Posted on

Use Nim language to implement Nim Game

Nim is a mathematical game of strategy in which two players take turns removing (or "nimming") objects from distinct heaps or piles. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap or pile. Depending on the version being played, the goal of the game is either to avoid taking the last object, or to take the last object.

From wiki: https://en.wikipedia.org/wiki/Nim

Nim language is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.

The code

We write a simple program based on command line. It mostly uses terminal module to format output, namely styledEcho.

We use parameters paramStr to get the total numbers of objects. Use readline to continue to get the out output of user. Use random ranging from 1 ~ 3 to emulate operations that computers execute.

import random, terminal, strutils, os


const TOTAL = 12

proc tryParseInt(s: string): int =
  try:
    result = parseInt(s)
  except ValueError:
    discard

proc succeed() =
  styledEcho(styleBright, fgRed, repeat('#', 50))
  styledEcho(styleDim, fgBlue, "Congratulations!")
  styledEcho(styleBright, fgRed, repeat('#', 50))

proc fail() =
  styledEcho(styleBright, fgGreen, repeat('#', 50))
  styledEcho(styleDim, fgBlue, "Don't lose heart. Come again next time:-)")


proc nimgame(total: int = TOTAL) =
  var
    total = total
    number: int
  randomize()
  while total > 1:
    styledEcho(styleDim, fgBlue, $total & " left" & "\n")
    styledEcho(styleBright, fgRed, "It's your turn")
    styledEcho(styleItalic, fgYellow, "fetch your stones(1 ~ 3): ")
    number = tryParseInt(readLine(stdin))
    while number notin {1, 2, 3}:
      styledEcho(styleItalic, fgYellow, "fetch your stones(1 ~ 3): ")
      number = tryParseInt(readLine(stdin))
    styledEcho(styleDim, fgBlue, "\nYou fetches: " & $number)
    dec(total, number)
    if total == 1:
      succeed()
      return
    if total > 1:
      let choice = rand(1 .. min(3, total))
      styledEcho(styleDim, fgBlue, "Computer fetches: " & $choice)
      dec(total, choice)
      if total == 0:
        succeed()
        return
  styledEcho(styleDim, fgBlue, $total & " left" & "\n")
  fail()


when isMainModule:
  if paramCount() < 1:
    echo "Please input the total numbers of stones!"
  if paramCount() == 1:
    var total = tryParseInt(paramStr(1))
    if total == 0:
      total = 21
    nimgame(total)
Enter fullscreen mode Exit fullscreen mode

Now play in windows.

Alt Text

Top comments (2)

Collapse
 
ringabout profile image
ringabout

I love Nim's indentation grammar, static type and efficiency.Before I use Nim, I am familiar with Python.
There exists an introduction so it's simple for me to learn Nim. Nim language is very interesting.
github.com/nim-lang/Nim/wiki/Nim-f...

 
ringabout profile image
ringabout

It's just my taste.Because I think Nim is more elegant. 😄