SHOW:
|
|
- or go back to the newest paste.
1 | os.loadAPI("button") | |
2 | local mainMonitor = "top" | |
3 | GamePanel = peripheral.wrap(mainMonitor) | |
4 | GamePanel.clear() | |
5 | ControlPanel = peripheral.wrap("right") | |
6 | - | ControlPanel.clear() |
6 | + | |
7 | - | local xc, yc = ControlPanel.getSize() |
7 | + | function writeMessage(message, monitor) |
8 | - | function writeMessage(message) |
8 | + | local xc, yc = ControlPanel.getSize() |
9 | - | ControlPanel.setCursorPos(math.floor((xc - string.len(message))/2+1),yc/2 + 1) |
9 | + | ControlPanel.clear() |
10 | - | ControlPanel.write(message) |
10 | + | ControlPanel.setCursorPos(math.floor((xc - string.len(message))/2+1),yc/2 + 1) |
11 | ControlPanel.write(message) | |
12 | - | writeMessage("CrossTurn") |
12 | + | |
13 | ||
14 | local xo, yo = GamePanel.getSize() | |
15 | print("Width: "..xo) | |
16 | print("Height: "..yo) | |
17 | local width = math.floor((xo-2)/3) | |
18 | local height = math.floor((yo-2)/3) | |
19 | print("Box width: "..width) | |
20 | - | sleep(0) |
20 | + | |
21 | ||
22 | function getEnemy(pPlayer) | |
23 | - | local x = params["x"] |
23 | + | if pPlayer == "x" then |
24 | - | local y = params["y"] |
24 | + | return "o" |
25 | - | print("Field at "..x..","..y.." was clicked") |
25 | + | elseif pPlayer == "o" then |
26 | return "x" | |
27 | - | --fx setup |
27 | + | else |
28 | - | --0,0 1,0 2,0 |
28 | + | print("Player \""..pPlayer.."\" has no opponent! (returning nil)") |
29 | - | --0,1 1,1 2,1 |
29 | + | return nil |
30 | - | --0,2 1,2 2,2 |
30 | + | end |
31 | end | |
32 | ||
33 | - | for x = 0,2 do |
33 | + | activePlayer = "x" |
34 | - | for y = 0,2 do |
34 | + | nextGameActivePlayer = getEnemy(activePlayer) |
35 | - | local xPos = x * width + x + 1 |
35 | + | winner = "empty" |
36 | - | local yPos = y * height + y + 1 |
36 | + | |
37 | - | print("Drawing button "..x..","..y.." at "..xPos..","..yPos.."...") |
37 | + | function newGame() |
38 | - | button.setTable(x..y, fx, {["x"] = x, ["y"] = y}, xPos, xPos + width - 1, yPos, yPos + height - 1) |
38 | + | winner = "empty" |
39 | - | end |
39 | + | clearAll() |
40 | - | end |
40 | + | fillTable() |
41 | - | button.screen() |
41 | + | activePlayer = nextGameActivePlayer |
42 | nextGameActivePlayer = getEnemy(nextGameActivePlayer) | |
43 | end | |
44 | ||
45 | - | event,side,x,y = os.pullEvent("monitor_touch") |
45 | + | function getPlayerTable() |
46 | - | if side == mainMonitor then |
46 | + | local tbl = {} |
47 | - | button.checkxy(x,y) |
47 | + | for x = 0,2 do |
48 | - | end |
48 | + | tbl[x] = {} |
49 | for y = 0,2 do | |
50 | tbl[x][y] = button.getPlayer(x..y) | |
51 | end | |
52 | - | --button.heading("TicTacToe") |
52 | + | end |
53 | return tbl | |
54 | end | |
55 | - | getClick() |
55 | + | |
56 | function checkGameOver() | |
57 | local p1 = "x" | |
58 | local p2 = "o" | |
59 | local p3 = "empty" | |
60 | ||
61 | --Get player information | |
62 | local tbl = getPlayerTable() | |
63 | ||
64 | --Check draw | |
65 | local countNotEmpty = 0 | |
66 | for x = 0,2 do | |
67 | for y = 0,2 do | |
68 | if tbl[x][y] ~= p3 then | |
69 | countNotEmpty = countNotEmpty + 1 | |
70 | end | |
71 | end | |
72 | end | |
73 | if countNotEmpty == 9 then | |
74 | return true, p3, {} | |
75 | end | |
76 | ||
77 | -- Check win | |
78 | local countColumns = {[p1] = 0, [p2] = 0} | |
79 | local countRows = {[p1] = 0, [p2] = 0} | |
80 | local countDiagonal1 = {[p1] = 0, [p2] = 0} | |
81 | local countDiagonal2 = {[p1] = 0, [p2] = 0} | |
82 | ||
83 | for a = 0,2 do | |
84 | countColumns = {[p1] = 0, [p2] = 0} | |
85 | countRows = {[p1] = 0, [p2] = 0} | |
86 | for b = 0,2 do | |
87 | if tbl[a][b] ~= p3 then | |
88 | countColumns[tbl[a][b]] = countColumns[tbl[a][b]] + 1 | |
89 | end | |
90 | if tbl[b][a] ~= p3 then | |
91 | countRows[tbl[b][a]] = countRows[tbl[b][a]] + 1 | |
92 | end | |
93 | end | |
94 | ||
95 | if tbl[a][a] ~= p3 then | |
96 | countDiagonal1[tbl[a][a]] = countDiagonal1[tbl[a][a]] + 1 | |
97 | end | |
98 | if tbl[a][2 - a] ~= p3 then | |
99 | countDiagonal2[tbl[a][2 - a]] = countDiagonal2[tbl[a][2 - a]] + 1 | |
100 | end | |
101 | ||
102 | if countColumns[p1] == 3 then | |
103 | return true, p1, {{["x"] = a, ["y"] = 0},{["x"] = a, ["y"] = 1},{["x"] = a, ["y"] = 2}} | |
104 | elseif countColumns[p2] == 3 then | |
105 | return true, p2, {{["x"] = a, ["y"] = 0},{["x"] = a, ["y"] = 1},{["x"] = a, ["y"] = 2}} | |
106 | end | |
107 | if countRows[p1] == 3 then | |
108 | return true, p1, {{["x"] = 0, ["y"] = a},{["x"] = 1, ["y"] = a},{["x"] = 2, ["y"] = a}} | |
109 | elseif countRows[p2] == 3 then | |
110 | return true, p2, {{["x"] = 0, ["y"] = a},{["x"] = 1, ["y"] = a},{["x"] = 2, ["y"] = a}} | |
111 | end | |
112 | end | |
113 | ||
114 | if countDiagonal1[p1] == 3 then | |
115 | return true, p1, {{["x"] = 0, ["y"] = 0},{["x"] = 1, ["y"] = 1},{["x"] = 2, ["y"] = 2}} | |
116 | elseif countDiagonal1[p2] == 3 then | |
117 | return true, p2, {{["x"] = 0, ["y"] = 0},{["x"] = 1, ["y"] = 1},{["x"] = 2, ["y"] = 2}} | |
118 | end | |
119 | if countDiagonal2[p1] == 3 then | |
120 | return true, p1, {{["x"] = 0, ["y"] = 2},{["x"] = 1, ["y"] = 1},{["x"] = 2, ["y"] = 0}} | |
121 | elseif countDiagonal2[p2] == 3 then | |
122 | return true, p2, {{["x"] = 0, ["y"] = 2},{["x"] = 1, ["y"] = 1},{["x"] = 2, ["y"] = 0}} | |
123 | end | |
124 | ||
125 | return false, p3, {} | |
126 | end | |
127 | ||
128 | function getPlayerName(pPlayer) | |
129 | if pPlayer == "x" then | |
130 | return "Cross" | |
131 | elseif pPlayer == "o" then | |
132 | return "Circle" | |
133 | elseif pPlayer == "empty" then | |
134 | print("Player \"empty\" has no name! (returning \"empty\")") | |
135 | return "empty" | |
136 | else | |
137 | print("Player \""..pPlayer.."\" has is invalid! (returning nil)") | |
138 | return nil | |
139 | end | |
140 | end | |
141 | ||
142 | function fx(params) | |
143 | local x = params["x"] | |
144 | local y = params["y"] | |
145 | print("Field at "..x..","..y.." was clicked") | |
146 | if button.getPlayer(x..y) == "empty" then | |
147 | print(getPlayerName(activePlayer).." occupied the field at "..x..","..y..".") | |
148 | button.setPlayer(x..y, activePlayer) | |
149 | activePlayer = getEnemy(activePlayer) | |
150 | local gameOver, winner, wInformation = checkGameOver() | |
151 | if gameOver then | |
152 | print("Game over: "..getPlayerName(winner).." has won.") | |
153 | for a,b in pairs(wInformation) do | |
154 | button.setState(b["x"]..b["y"], true) | |
155 | end | |
156 | if winner == "empty" then | |
157 | writeMessage("Draw! Try again...") | |
158 | else | |
159 | writeMessage(getPlayerName(winner).." has won!", ControlPanel) | |
160 | end | |
161 | else | |
162 | writeMessage(getPlayerName(activePlayer).."\'s turn!", ControlPanel) | |
163 | end | |
164 | else | |
165 | print(getPlayerName(activePlayer).." cannot occupy the field at "..x..","..y..". It is already occupied by "..getPlayerName(button.getPlayer(x..y))..".") | |
166 | end | |
167 | end | |
168 | ||
169 | function fillTable() | |
170 | for x = 0,2 do | |
171 | for y = 0,2 do | |
172 | -- local pos = fieldIndex * FieldWidth + borderIndex * borderWidth(=1) + monitorIndex (0,1,2,3 -> 1,2,3,4) | |
173 | local xPos = x * width + x + 1 | |
174 | local yPos = y * height + y + 1 | |
175 | print("Drawing button "..x..","..y.." at "..xPos..","..yPos.." to the monitor on the top...") | |
176 | button.setTable(x..y, fx, {["x"] = x, ["y"] = y}, xPos, xPos + width - 1, yPos, yPos + height - 1, "top") | |
177 | end | |
178 | end | |
179 | button.screen() | |
180 | end | |
181 | ||
182 | function getClick() | |
183 | event,side,x,y = os.pullEvent("monitor_touch") | |
184 | button.checkxy(x, y, side) | |
185 | end | |
186 | ||
187 | fillTable() | |
188 | ||
189 | while true do | |
190 | getClick() | |
191 | end |