Gilded rose in Nim

- I've started with a small refactor, Command to function. This was done as
   the most obvious way to do it (to me) as in the original, would not compile
   in Nim due to violating memory lifetimes. I could have made it take a
   ref seq[Item], but then I would need to instatiate a ref seq and I didn't
   want to make a change that drastic. Also due to Nim's UFCS, the ultimate
   implementation would be basically the same anyway.
This commit is contained in:
Kieran 2020-10-16 18:59:43 +08:00
parent e2c5826e71
commit 908055ba3e
No known key found for this signature in database
GPG Key ID: A8DDD92D96F2EFD3
3 changed files with 173 additions and 0 deletions

35
nim/src/gildedrose.nim Normal file
View File

@ -0,0 +1,35 @@
import items
proc updateQuality*(items: var seq[Item]) =
for i in 0 ..< items.len:
if items[i].name != "Aged Brie" and items[i].name != "Backstage passes to a TAFKAL80ETC concert":
if items[i].quality > 0:
if items[i].name != "Sulfuras, Hand of Ragnaros":
items[i].quality = items[i].quality - 1
else:
if items[i].quality < 50:
items[i].quality = items[i].quality + 1
if items[i].name == "Backstage passes to a TAFKAL80ETC concert":
if items[i].sellIn < 11:
if items[i].quality < 50:
items[i].quality = items[i].quality + 1
if items[i].sellIn < 6:
if items[i].quality < 50:
items[i].quality = items[i].quality + 1
if items[i].name != "Sulfuras, Hand of Ragnaros":
items[i].sellIn = items[i].sellIn - 1
if items[i].sellIn < 0:
if items[i].name != "Aged Brie":
if items[i].name != "Backstage passes to a TAFKAL80ETC concert":
if items[i].quality > 0:
if items[i].name != "Sulfuras, Hand of Ragnaros":
items[i].quality = items[i].quality - 1
else:
items[i].quality = items[i].quality - items[i].quality
else:
if items[i].quality < 50:
items[i].quality = items[i].quality + 1

12
nim/src/items.nim Normal file
View File

@ -0,0 +1,12 @@
import strformat
type
Item* = object
name*: string
sellIn*, quality*: int
proc initItem*(name: string, sellIn, quality: int): Item =
Item(name: name, sellIn: sellIn, quality: quality)
proc `$`*(item: Item): string =
&"{item.name}, {item.sellIn}, {item.quality}"

126
nim/test/gilded.nim Normal file
View File

@ -0,0 +1,126 @@
import unittest
import ../src/items
import ../src/gildedrose
let list = @[
initItem("+5 Dexterity Vest", 10, 20),
initItem("Aged Brie", 2, 0),
# this doesn't have any special treatment, but if you want you can think of something and add a test
initItem("Elixir of the Mongoose", 5, 7),
initItem("Sulfuras, Hand of Ragnaros", 0, 80),
initItem("Sulfuras, Hand of Ragnaros", -1, 80),
initItem("Backstage passes to a TAFKAL80ETC concert", 15, 20),
initItem("Backstage passes to a TAFKAL80ETC concert", 10, 49),
initItem("Backstage passes to a TAFKAL80ETC concert", 5, 49),
# this conjured item does not work properly yet
initItem("Conjured Mana Cake", 3, 6)
]
template checkItem(item: Item, s, q: int) =
check:
item.sellIn == s
item.quality == q
proc days(count: int): seq[Item] =
var items = list
for _ in 1 .. count:
items.updateQuality()
items
suite "+5 Dexterity Vest [0]":
test "1 day":
var items = days(1)
checkItem(items[0], 9, 19)
test "5 days, check for cumulative depeciation":
let items = days(5)
checkItem(items[0], 5, 15)
test "10 days, expiration day":
let items = days 10
checkItem(items[0], 0, 10)
test "14 days, check for expired depreciation":
let items = days(14)
checkItem(items[0], -4, 2)
test "20 days, quality should not be negative":
let items = days 20
checkItem(items[0], -10, 0)
suite "Aged Brie [1]":
test "1 day, brie increases value":
let items = days(1)
checkItem(items[1], 1, 1)
test "2 days, expiration day":
let items = days(2)
checkItem(items[1], 0, 2)
test "4 days, extra increase after expiration":
let items = days(4)
checkItem(items[1], -2, 6)
test "30 days, should reach max quality":
let items = days 30
checkItem items[1], -28, 50
suite "Sulfuras, Hand of Ragnaros [3]":
test "1 day":
let items = days(1)
checkItem(items[3], 0, 80)
test "2 days":
let items = days(2)
checkItem(items[3], 0, 80)
suite "Sulfuras, Hand of Ragnaros [4]":
test "1 day":
let items = days(1)
checkItem(items[4], -1, 80)
suite "Backstage passes to a TAFKAL80ETC concert [5]":
test "1 day":
let items= days(1)
checkItem(items[5], 14, 21)
test "5 days":
let items = days 5
checkItem items[5], 10, 25
test "7 days, increase appreciation":
let items = days 7
checkItem items[5], 8, 29
test "12 days, extra increased appriciation":
let items = days 12
checkItem items[5], 3, 41
test "14 days, day before concert":
let items = days 14
checkItem items[5], 1, 47
test "16 days, day after concert":
let items = days 16
checkItem items[5], -1, 0
suite "Backstage passes to a TAFKAL80ETC concert [6]":
test "1 day, should reach max quality even though concert is soon":
let items = days 1
checkItem items[6], 9, 50
test "11 days, day after concert":
let items = days 11
checkItem items[6], -1, 0
suite "Backstage passes to a TAFKAL80ETC concert [7]":
test "1 day, should reach max quality even though concert is imminent":
let items = days 1
checkItem items[7], 4, 50
suite "Conjured Mana cake [8]":
test "1 day, should decrease by double":
let items = days 1
checkItem items[8], 2, 4