Design Question / Challenge - From SmartPy Contract to Yes, It's Just Ruby - Let's Play Nim (The Ancient Math Subtraction Game)
Gerald Bauer <[email protected]>
| Newsgroups | gmane.comp.lang.ruby.general |
|---|---|
| Message-ID | <CAAxEZd8nVpbrjz9Q4zu82N2synVxUxGx8h56wkchK=yMq+Y1Xg@mail.gmail.com> |
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
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>