Skip to content

Commit 60b5e28

Browse files
committed
simplified catch
1 parent d596642 commit 60b5e28

File tree

1 file changed

+61
-118
lines changed

1 file changed

+61
-118
lines changed

tool/rlc/test/examples/catch.rl

Lines changed: 61 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,108 @@
11
# RUN: rlc %s -o %t -i %stdlib
22

33
import serialization.print
4+
import range
45
import collections.vector
56
import machine_learning
67
import action
78

89
# Constants for the game
9-
const kDefaultRows = 10
10-
const kDefaultCols = 5
11-
const kNumCells = 50 # kDefaultRows * kDefaultCols
10+
const NUM_ROWS = 11
11+
const NUM_COLUMS = 5
1212

13-
# Cell states
14-
enum CellState:
15-
Empty
16-
Paddle
17-
Ball
13+
enum Direction:
14+
Left
15+
None
16+
Right
1817

19-
fun equal(CellState other) -> Bool:
18+
fun equal(Direction other) -> Bool:
2019
return self.value == other.value
2120

22-
fun not_equal(CellState other) -> Bool:
21+
fun not_equal(Direction other) -> Bool:
2322
return !(self.value == other.value)
2423

25-
# Board representation
26-
cls Board:
27-
BInt<2,99> num_rows
28-
BInt<2,99> num_cols
29-
BInt<0,98> ball_row
30-
BInt<0,98> ball_col
31-
BInt<0,98> paddle_col
32-
33-
fun init():
34-
self.num_rows.value = kDefaultRows
35-
self.num_cols.value = kDefaultCols
36-
self.paddle_col.value = kDefaultCols / 2
37-
38-
fun init(Int rows, Int cols):
39-
self.num_rows.value = rows
40-
self.num_cols.value = cols
41-
self.paddle_col.value = cols / 2
42-
43-
# Get cell state at specific row and column
44-
fun cell_at(Int row, Int col) -> CellState:
45-
if row == self.num_rows.value - 1 and col == self.paddle_col.value:
46-
return CellState::Paddle
47-
else if row == self.ball_row.value and col == self.ball_col.value:
48-
return CellState::Ball
49-
return CellState::Empty
50-
51-
# Check if the game is terminal
52-
fun is_terminal() -> Bool:
53-
return self.ball_row.value >= self.num_rows.value - 1
5424

55-
# Generate string representation of the board
56-
fun to_string() -> String:
57-
let result = ""s
58-
let row = 0
59-
while row < self.num_rows.value:
60-
let col = 0
61-
while col < self.num_cols.value:
62-
if self.cell_at(row, col) == CellState::Empty:
63-
result = result + "."s
64-
else if self.cell_at(row, col) == CellState::Paddle:
65-
result = result + "x"s
66-
else:
67-
result = result + "o"s
68-
col = col + 1
69-
result = result + "\n"s
70-
row = row + 1
71-
return result
25+
using Column = BInt<0, NUM_COLUMS>
26+
using Row = BInt<0, NUM_ROWS>
7227

7328
# The main Catch game
7429
@classes
7530
act play() -> Game:
76-
frm board : Board
31+
frm ball_row : Row
32+
frm ball_col : Column
33+
frm paddle_col : Column
7734

7835
# Initialization - chance player selects starting ball column
79-
act initialize(BInt<0, kDefaultCols> col) {
80-
col.value >= 0,
81-
col.value < kDefaultCols
82-
}
83-
board.ball_col.value = col.value
36+
act set_start_location(Column col)
37+
ball_col.value = col.value
38+
paddle_col = NUM_COLUMS / 2
8439

8540
# Game loop - player makes moves until ball reaches bottom
86-
while !board.is_terminal():
87-
act move(BInt<0, 2> direction) {
88-
direction >= 0,
89-
direction < 3
90-
}
91-
92-
# Move the ball down one row
93-
board.ball_row.value = board.ball_row.value + 1
41+
while ball_row != NUM_ROWS - 1:
42+
act move(Direction direction)
43+
44+
ball_row.value = ball_row.value + 1
9445

95-
# Move the paddle based on player's direction
96-
# 0 = left, 1 = stay, 2 = right
9746
let actual_direction = direction.value - 1 # Convert to -1, 0, 1
98-
let new_paddle_pos = board.paddle_col.value + actual_direction
47+
paddle_col = paddle_col.value + actual_direction
48+
49+
# Cell states
50+
enum CellState:
51+
Empty
52+
Paddle
53+
Ball
54+
55+
fun equal(CellState other) -> Bool:
56+
return self.value == other.value
57+
58+
fun not_equal(CellState other) -> Bool:
59+
return !(self.value == other.value)
60+
61+
# Get cell state at specific row and column
62+
fun cell_at(Game game, Int row, Int col) -> CellState:
63+
if row == NUM_ROWS - 1 and col == game.paddle_col.value:
64+
return CellState::Paddle
65+
else if row == game.ball_row.value and col == game.ball_col.value:
66+
return CellState::Ball
67+
return CellState::Empty
68+
9969

100-
# Ensure paddle stays within bounds
101-
if new_paddle_pos >= 0 and new_paddle_pos < board.num_cols.value:
102-
board.paddle_col.value = new_paddle_pos
10370

10471
# Function for machine learning components to display the game state
10572
fun pretty_print(Game game):
106-
print(game.board.to_string())
107-
108-
# Print game status
109-
if game.is_done():
110-
if score(game, 0) == 1.0:
111-
print("You win! You caught the ball."s)
112-
else:
113-
print("You lose! You missed the ball."s)
114-
else:
115-
print("Game in progress. Ball at row "s + to_string(game.board.ball_row) + ", column "s + to_string(game.board.ball_col))
116-
print("Paddle at column "s + to_string(game.board.paddle_col))
73+
# Generate string representation of the board
74+
let result = ""s
75+
for row in range(NUM_ROWS):
76+
for col in range(NUM_COLUMS):
77+
if cell_at(game, row, col) == CellState::Empty:
78+
result = result + "."s
79+
else if cell_at(game, row, col) == CellState::Paddle:
80+
result = result + "x"s
81+
else:
82+
result = result + "o"s
83+
result = result + "\n"s
84+
print(result)
85+
11786

11887
# Return current player or special value if game is done
11988
fun get_current_player(Game g) -> Int:
12089
if g.is_done():
12190
return -4 # Terminal state
91+
let column : Column
92+
if can g.set_start_location(column):
93+
return -1
12294
return 0 # Player 0 (the only player)
12395

12496
# Return score for ML training
12597
fun score(Game g, Int player_id) -> Float:
12698
if !g.is_done():
12799
return 0.0
128-
if g.board.paddle_col == g.board.ball_col:
100+
if g.paddle_col.value == g.ball_col.value:
129101
return 1.0
130102
else:
131-
return -1.0
103+
return 0.0
132104

133105
# Return number of players (always 1 for this game)
134106
fun get_num_players() -> Int:
135107
return 1
136108

137-
fun fuzz(Vector<Byte> input):
138-
let state = play()
139-
let x : AnyGameAction
140-
let enumeration = enumerate(x)
141-
let index = 0
142-
while index + 8 < input.size() and !state.is_done():
143-
let num_action : Int
144-
from_byte_vector(num_action, input, index)
145-
if num_action < 0:
146-
num_action = num_action * -1
147-
if num_action < 0:
148-
num_action = 0
149-
150-
let executable : Vector<AnyGameAction>
151-
let i = 0
152-
#print("VALIDS")
153-
while i < enumeration.size():
154-
if can apply(enumeration.get(i), state):
155-
#print(enumeration.get(i))
156-
executable.append(enumeration.get(i))
157-
i = i + 1
158-
#print("ENDVALIDS")
159-
#if executable.size() == 0:
160-
#print("zero valid actions")
161-
#print(state)
162-
#return
163-
164-
print(executable.get(num_action % executable.size()))
165-
apply(executable.get(num_action % executable.size()), state)

0 commit comments

Comments
 (0)