Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- The function get_name() should return a single string that is the name of the puzzle.
- --
- function get_name()
- return "NON-TRANSITIVE DICE BALANCED"
- end
- -- The function get_description() should return an array of strings, where each string is
- -- a line of description for the puzzle. Surrounding text with asterisks will cause it to
- -- be rendered in bold, something we use when mentioning a signal by name.
- --
- -- By using the syntax that we use in our puzzle descriptions, you can also create tables:
- --
- -- "| This is a table. | This is a second column. | This is a column with "
- -- "| | | multiple line of text."
- -- "----------------------------------------------------------------------"
- -- "| This is a second | | More text here! "
- -- "| table row. | | "
- --
- -- Puzzle descriptions are not automatically paginated, so you can use the string "<PAGE>"
- -- to start a new page of text. If you don't it will overflow and make Zach sad.
- --
- function get_description()
- return {
- "*input* is an XBus input connected to a dice database.",
- "*Radio rx* is a non-blocking XBus input connected to a tester.",
- "*Radio tx* is an XBus output connected to an evaluation device.",
- "Values from *input* and *rx* come in packets of 6 with values in range [1-9], in ascending order.",
- "Compare the values on the sides of the die from *rx* to the *input* die.",
- "If the *rx* die is better, output 1. If *input* die is better, output -1. If both are equal, output 0.",
- "<PAGE>",
- "Sides of one die are compared to each other side of the other. The larger number wins, otherwise it is a tie.",
- "There are 36 direct comparisons. For example, 15 wins, 10 ties and 11 loses; means overall win (15 > 11).",
- "For this puzzle, sums of all die are balanced.",
- }
- end
- -- The function get_board() allows you to specify an 18x7 "ASCII art" grid to customize
- -- the layout of the board and the placement of the input and output terminals. Generally
- -- speaking, inputs are placed on the left of boards, while outputs are placed on the right.
- --
- -- For empty space, use the '.' character.
- -- For buildable board space, use the '#' character.
- -- For an input or output terminal, use characters '0' through '9' no more than once each.
- -- For the bottom-left corner of the radio, use the 'R' character.
- -- For the bottom-left corners of dials, use characters 'A', 'B', and 'C'.
- --
- function get_board()
- return [[
- #################0
- ##################
- ##################
- ##################
- ##################
- ##################
- ##################
- ]]
- end
- -- The function get_data() is called both to establish information about the puzzle (such as what
- -- the inputs and outputs are) and to generate the random test cases. Signal levels and XBus data
- -- should change from call to call, but information like the names and types of terminals should
- -- not change at all.
- --
- -- To create a standard input or output terminal, call create_terminal(). Valid terminal types are
- -- TYPE_SIMPLE, TYPE_XBUS, and TYPE_XBUS_NONBLOCKING. Valid terminal directions are DIR_INPUT and
- -- DIR_OUTPUT. Valid data for a simple I/O signal is an array of integers, 0 - 100 inclusive. Valid
- -- data for an XBus signal is an array of integer arrays, each with values -999 to 999 inclusive.
- --
- -- create_terminal(name, board_character, type, direction, data)
- --
- -- To create a radio (C2S-RF901), call create_radio(). You may only create one radio in each puzzle.
- -- Since radios are XBus-only, the only valid data for data_rx and data_tx are arrays of integer arrays,
- -- each with values -999 to 999 inclusive. You cannot customize the signal names for a radio.
- --
- -- By default the radio will be placed in the bottom-left corner of the screen. However, if you use an
- -- 'R' character in your board layout, the bottom-left corner of the radio will be placed there instead.
- --
- -- create_radio(data_rx, data_tx)
- --
- -- To create a dial (N4DL-1000), call create_dial(). You may create up to three dials in each puzzle.
- -- The names of dials should be kept short, as there is not much room to display them visually. A valid
- -- value is an integer between 0 and 99, inclusive.
- --
- -- By default dials will be placed in the bottom-left corner of the screen. However, if you use an
- -- 'A', 'B', or 'C' character in your board layout, the bottom-left corners of the first, second, and
- -- third dials will be placed there, respectively.
- --
- -- create_dial(name, value)
- --
- -- NOTE: To generate random values you should use math.random(). However, you SHOULD NOT seed
- -- the random number generator with a new seed value, as that is how the game ensures that
- -- the first test run is consistent for all users, and thus something that allows for the
- -- comparison of cycle scores.
- --
- -- NOTE: Fun fact! Arrays in Lua are implemented as tables (dictionaries) with integer keys that
- -- start at 1 by convention. Contrast this with nearly every other programming language, in
- -- which arrays start with an index of 0. Because of this, the 60 "time slices" that make
- -- up a test case are indexed from 1 to 60 inclusive.
- --
- function gen_dice(num, iteration)
- local tablu = {}
- local index = 1
- if (iteration == 0) then
- if num < 10 then
- return {{num}}
- else
- return {}
- end
- else
- local t = 1
- while (t+iteration <= num) and (not (t == 10)) do
- local rest = gen_dice_memoized(num-t, iteration-1)
- for x = 1, #rest do
- if t <= rest[x][1] then
- table.insert(rest[x], 1, t)
- tablu[index] = rest[x]
- index = index + 1
- end
- end
- t = t + 1
- end
- end
- return tablu
- end
- gen_dice_memo = {}
- function gen_dice_memoized(num, iteration)
- if gen_dice_memo[num] == nil then
- gen_dice_memo[num] = {}
- end
- local result;
- if gen_dice_memo[num][iteration] == nil then
- result = gen_dice(num, iteration)
- gen_dice_memo[num][iteration] = result
- else
- result = gen_dice_memo[num][iteration]
- end
- -- quick hack to deep-copy the result
- local resultcopy = {}
- for key, value in pairs(result) do
- resultcopy[key] = {table.unpack(result[key])}
- end
- return resultcopy
- end
- function compare(d1, d2)
- win = 0
- loss = 0
- tie = 0
- for x = 1, 6 do
- for y = 1, 6 do
- if d1[x] == d2[y] then
- tie = tie + 1
- elseif d1[x] > d2[y] then
- win = win + 1
- else
- loss = loss + 1
- end
- end
- end
- if win > loss then
- return "win"
- elseif loss > win then
- return "loss"
- else
- return "tie"
- end
- end
- function get_data()
- a = gen_dice_memoized(18, 5)
- input = {}
- inputD = {}
- output = {}
- time = 1
- bias = math.random(0, 10)
- cumulative = math.random(11+bias, 49-bias)
- die = gen_dice_memoized(cumulative, 5)
- set = die[math.random(1, #die)]
- inputD[time] = set
- while time <= 60 do
- time = time + math.random(0, math.random(0, 4))
- newinput = die[math.random(1, #die)]
- input[time] = newinput
- result = compare(set, newinput)
- if result == "win" then
- output[time] = {1}
- elseif result == "loss" then
- output[time] = {-1}
- else
- output[time] = {0}
- end
- time = time + 6
- end
- create_terminal("Input", "0", TYPE_XBUS, DIR_INPUT, input)
- create_radio(inputD, output)
- end
Advertisement
Add Comment
Please, Sign In to add comment