loading...
Cover image for Use Nim language to implement Nim Game

Use Nim language to implement Nim Game

xflywind profile image flywind ・2 min read

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)

Now play in windows.

Alt Text

Discussion

markdown guide
 
 

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...

 

Why not Rust, then?

It has got more traction than NIM and except for indentation, it gives you static safety and efficiency with no overhead. Furthermore, judging from your code, it offers more safety as NIM seems to implement the old-style error handling with exception raising.

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