1
2
3
4
5
6
7
8
|
global clientRequestGameMsg = "0:S:0:0:0"
global clientTestMsg = "2:myAuth:1:2:2:1:3:1:0:0:0:0:0:0"
c1 = connect(8088)
println(c1, clientRequestGameMsg)
println("waiting for host response")
hostResponse = readline(c1)
hostResponse = chomp(hostResponse)
println("host response:$hostResponse")
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
using SQLite
global clientConnection
global databaseName = "clientTest.db" #client wont be choosing the name this time, so we'll pick an arbitrary filename
global disconnected = false
global hostResponse
global fileName #Will refer to the db file generated by the host locally
global authString
global receivedPayload = Array{Int64}(14)
fill!(receivedPayload, 0)
global receivedPayload1 #Since these can contain characters, they'll be tracked seperately from the rest of the client payload array
global receivedPayload2 #Since these can contain characters, they'll be tracked seperately from the rest of the client payload array
global receivedPayloadOption #Can be a ! character, it will be tracked seperately from the rest of the client payload array
#Expected positions of wincode, authString, and option
global expectedMessageLength = 14
global wincodePosition = 1
global authStringPosition = 2
global optionPosition = 9
#Test messages
global clientRequestGameMsg = "0:S:0:0:0"
global clientTestMsg = "2:myAuth:1:2:2:1:3:1:0:0:0:0:0:0"
#For building the game type to be played. Will eventually be provided by the user through the GUI.
global clientPortToJoin
global clientGameType
global clientCheating
global clientTimeLimit
global clientTimeAdd
function resetReceivedPayload()
global receivedPayload
global receivedPayload1 = "0"
global receivedPayload2 = "0"
global receivedPayloadOption = "0"
for i in eachindex(receivedPayload)
receivedPayload[i] = 0
end
end
function buildRequestGameMessage(gameType, cheating, timelimit, timeadd)
requestStr = string("0:$gameType:$cheating:$timelimit:$timeadd")
return requestStr
end
#Convert the received message. Return false if a non-move is detected, true otherwise.
function clientReadPayload(receivedMsg)
global receivedPayload
global receivedPayload1
global receivedPayload2
global receivedPayloadOption
global authString
global wincodePosition
global authStringPosition
global optionPosition
#wincode, authString, and option can contain characters, so they will be stored seperately from the the rest of the client payload
#basically skipping clientPayload[1], clientPayload[2], and clientPayload[9]
resetReceivedPayload()
receivedMsg = chomp(receivedMsg) #Removing the \n from the end of the string
splitMsg = split(receivedMsg, ":")
#Checking for unusual or bad payloads
if (length(splitMsg) != expectedMessageLength || splitMsg[2] != authString) #Likely received an incomplete message or error message, not a move
println("PATQA::readPayload detected non-move payload. authString = $authString length = ", length(splitMsg))
try
receivedPayload1 = splitMsg[1]
receivedPayload2 = splitMsg[2]
catch
println("PATQA::Unable to set receivedPayload[1] or receivedPayload[2]. receivedMsg = $receivedMsg")
return false
end
return false
end
receivedPayload1 = splitMsg[wincodePosition]
receivedPayload2 = splitMsg[authStringPosition]
receivedPayloadOption = splitMsg[optionPosition] #Expecting option field to be in position 9
for i in 1:length(splitMsg)
#Skipping locations that could involve characters instead of ints
if ( i == wincodePosition || i == authStringPosition || i == optionPosition )
#Skip
else
receivedPayload[i] = parse(Int64, splitMsg[i])
println("PATQA:: receivedPayload[ $i ] = ", receivedPayload[i])
end
end
return true
end
#To be used in conjunction with the network specification naming format for the args
function initializeDatabase(name, gameType, cheating, timeLimitArg, timeAddArg)
gameSeed = round(Int64, time()*1000000000)
#Remove the old database file if it already exists
rm(name; force=true)
global fileName = SQLite.DB(name)
#Creates the db file
SQLite.query(fileName, "CREATE TABLE meta(key varchar(255) PRIMARY KEY, value varchar(255));")
SQLite.query(fileName, "CREATE TABLE moves(move_number int PRIMARY KEY, move_type varchar(6), sourcex int, sourcey int, targetx int, targety int, option varchar(4), i_am_cheating bit, targetx2 int, targety2 int, targetx3 int, targety3 int);")
if gameType == "S"
SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','standard');")
elseif gameType == "M"
SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','minishogi');")
elseif gameType == "C"
SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','chu');")
elseif gameType == "T"
SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','ten');")
end
if cheating == "1"
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('legality', 'cheating');")
else
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('legality', 'legal');")
end
#If the user didn't specify a time limit or set the limit to 0, the game is not timed
#The time_add, sente_time, and gote_time rows are only inserted if there is a time limit
if timeLimitArg != "0"
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('timed', 'yes');")
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('time_add', '$timeAddArg');")
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('sente_time', '$timeLimitArg');")
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('gote_time', '$timeLimitArg');")
else
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('timed', 'no');")
end
SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('seed', $gameSeed);")
end
#Returns empty string if there are no moves in the db, or a payload format string otherwise
#<wincode>:<authString>:<movenum>:<movetype>:<sourcex>:<sourcey>:<targetx>:<targety>:<option>:<cheating>:<targetx2>:<targety2>:<targetx3>:<targety3>
function readLastMove(dbFile)
global authString
payloadString = ""
#tempDB = SQLite.DB(dbFile)
dbLastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
#Getting the int value from the nullableArray data type
moveNumber = get(dbLastMoveNumber[1][1], -1)
if(moveNumber == -1)
println("PATQA::readLastMove detected no moves in database")
return payloadString
end
moveTypeTable = SQLite.query(fileName,"SELECT move_type FROM moves WHERE move_number=$moveNumber")
#NOTE WE'RE NOT USING DATABASE ROW EXCHANGE
#This is exclusively for building a payload message, not manipulating our chessboard!
moveType = get((SQLite.query(fileName,"SELECT move_type FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
xSource = get((SQLite.query(fileName,"SELECT sourcex FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
ySource = get((SQLite.query(fileName,"SELECT sourcey FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
xTarget = get((SQLite.query(fileName,"SELECT targetx FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
yTarget = get((SQLite.query(fileName,"SELECT targety FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
xTarget2 = get((SQLite.query(fileName,"SELECT targetx2 FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
yTarget2 = get((SQLite.query(fileName,"SELECT targety2 FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
xTarget3 = get((SQLite.query(fileName,"SELECT targetx3 FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
yTarget3 = get((SQLite.query(fileName,"SELECT targety3 FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
option = get((SQLite.query(fileName,"SELECT option FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
isCheating = get((SQLite.query(fileName,"SELECT i_am_cheating FROM moves WHERE move_number=$moveNumber"))[1][1], 0)
if moveType == "move"
payloadString = string("9:$authString:$moveNumber:1:$xSource:$ySource:$xTarget:$yTarget:$option:$isCheating:$xTarget2:$yTarget2:$xTarget3:$yTarget3")
elseif moveType == "drop"
payloadString = string("9:$authString:$moveNumber:2:$xSource:$ySource:$xTarget:$yTarget:$option:$isCheating:$xTarget2:$yTarget2:$xTarget3:$yTarget3")
elseif moveType == "resign"
payloadString = string("9:$authString:$moveNumber:3:$xSource:$ySource:$xTarget:$yTarget:$option:$isCheating:$xTarget2:$yTarget2:$xTarget3:$yTarget3")
else
#bad move detected
println("PATQA::readLastMove bad move detected")
end
println("PATQA::payloadString = $payloadString")
return payloadString
end
###BEGIN RUNTIME CODE###
#Hardcoded values until GUI is integrated
clientPortToJoin = 8088
clientGameType = "S"
clientCheating = "0"
clientTimeLimit = "0"
clientTimeAdd = "0"
clientRequestGameMsg = buildRequestGameMessage(clientGameType, clientCheating, clientTimeLimit, clientTimeAdd)
println("PATQA::clientRequestGameMsg = $clientRequestGameMsg")
#Initilizing client's database file
initializeDatabase(databaseName, clientGameType, clientCheating, clientTimeLimit, clientTimeAdd)
#Connecting to host
println("Connecting to host via port $clientPortToJoin...")
clientConnection = connect(clientPortToJoin)
#Sending request game message
println(clientConnection, clientRequestGameMsg)
println("Request game sent. Waiting for host response...")
try
global hostResponse
hostResponse = readline(clientConnection)
hostResponse = chomp(hostResponse)
println("PATQA::Host response:$hostResponse")
catch
println("hostResponse readline failed. Host disconnected?")
end
#Checking validity of response.
if(clientReadPayload(hostResponse))
global authString = receivedPayload2
else
println("PATQA::UNUSUAL PAYLOAD DETECTED. hostResponse = $hostResponse")
end
#If we are player 2, we must wait for the host to send us a move.
if(hostResponse[1] == 1)
try
global hostResponse
hostResponse = readline(clientConnection)
hostResponse = chomp(hostResponse)
println("PATQA::Host 2nd response:$hostResponse")
catch
println("PATQA::readline failed waiting for host's first move. Host disconnected?")
end
end
println("PATQA::END OF clientTest.jl")
|