Design Question / Challenge - From SmartPy Contract to Yes, It's Just Ruby - Let's Play Nim (The Ancient Math Subtraction Game)

(Gerald Bauer) #1

Hello,

  Here's another design question / challenge:

  Turn the SmartPy contract that lets you play Nim (the ancient math
subtraction game) into a "Yes, It's Just Ruby" version. Example:

  import smartpy as sp

  class NimGame(sp.Contract):
      def __init__(self, size, bound = None, winnerIsLast = False):
          self.bound = bound
          self.winnerIsLast = winnerIsLast
          self.init(deck = sp.range(1, size + 1),
                    size = size,
                    nextPlayer = 1,
                    claimed = False,
                    winner = 0)

      @sp.message
      def remove(self, data, params):
          cell = params.cell
          k = params.k
          sp.check(0 <= cell)
          sp.check(cell < data.size)
          sp.check(1 <= k)
          if self.bound is not None:
              sp.check(k <= self.bound)
          sp.check(k <= data.deck[cell])
          sp.set(data.deck[cell], data.deck[cell] - k)
          sp.set(data.nextPlayer, 3 - data.nextPlayer)

      @sp.message
      def claim(self, data, params):
          sp.check(sp.sum(data.deck) == 0)
          sp.set(data.claimed, True)
          if self.winnerIsLast:
              sp.set(data.winner, 3 - data.nextPlayer)
          else:
              sp.set(data.winner, data.nextPlayer)

  What's SmartPy?

  The SmartPy library for programming contracts with Python
(see Introducing SmartPy [1]) compiles to SmartML and onto Michelson bytecode.

   What's Nim?

Nim is a mathematical game of strategy in which two players take turns
removing objects from distinct heaps. 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. The goal of the game is to avoid
taking the last object.

(Source: Nim @ Wikipedia [2])

  And here's my (second) take [3] with an alternate
   "meta" parameterized contract template / factory
   and yes, it's ruby:

···

####################################
# Nim Game Contract Template
#
# Parameter Options:
# - bound (default: nil)
# - winner_is_last (default: false)

sig [Integer],
def setup( size )
  @deck = Array( 1...size+1 ) ## e.g. [1,2,3,4,...]
  @size = size
  @next_player = 1
  @claimed = false
  @winner = 0
end

# cell - representing a cell from an array
# k - a quantity to remove from this cell
sig [Integer, Integer],
def remove( cell, k )
  assert 0 <= cell
  assert cell < @size
  assert 1 <= k
  if $DEFINED[:bound]
    assert k <= $PARA[:bound]
  end
  assert k <= @deck[cell]

  @deck[cell] -= k
  @nextPlayer = 3 - @nextPlayer ## toggles between 1|2
end

def claim
  assert @deck.sum == 0

  @claimed = true
  if $TRUE[:winner_is_last]
    @winner = 3 - @nextPlayer
  else
    @winner = @nextPlayer
  end
end

   Can you do better? Yes, you can. Post your code snippets, ideas,
critiques, comments, etc.

   Cheers. Prost.

[1] https://medium.com/@SmartPy_io/introducing-smartpy-and-smartpy-io-d4013bee7d4e
[2] https://en.wikipedia.org/wiki/Nim
[3] https://github.com/s6ruby/ruby-to-michelson#bonus-secure-ruby-to-smartpy-to-smartml--michelson-source-to-source-cross-compiler-cheat-sheet

0 Likes