Skip to content

Commit a3c51c6

Browse files
committed
Select name from only allowed characters while trying to be as close to zigbot as possible
1 parent 1d6f62f commit a3c51c6

File tree

4 files changed

+108
-27
lines changed

4 files changed

+108
-27
lines changed

src/Config.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
millis: u32,
2+
maxPlayers: u32,
3+
boardX: u32,
4+
boardY: u32,
5+
startResources: u32,
6+
unitsToWin: u32,
7+
resourceHp: u32,
8+
unitHp: u32,
9+
unitDamage: u32,
10+
allowedNameCharacters: []const u8,

src/NameIterator.zig

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
const std = @import("std");
2+
const Self = @This();
3+
4+
const prefferedChars = [_][]const u8{
5+
"zZ2sS", "iI1lL", "gGqQ", "bB", "oO0Q", "tT7",
6+
};
7+
8+
name: [9]u8 = [9]u8{ 'z', 'i', 'g', 'b', 'o', 't', '!', '!', '!' },
9+
allowedChars: []const u8,
10+
prefferedPos: [6]u8 = [6]u8{ 0, 0, 0, 0, 0, 0 },
11+
allowedPos: [9]u8 = [9]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
12+
charId: u4 = 6,
13+
nameLen: u4 = 6,
14+
15+
fn in(char: u8, allowed: []const u8) bool {
16+
for (allowed) |c| {
17+
if (char == c) return true;
18+
}
19+
return false;
20+
}
21+
22+
fn fail(self: *Self) bool {
23+
for (self.allowedPos) |pos| {
24+
if (pos != self.allowedChars.len) return false;
25+
}
26+
return true;
27+
}
28+
29+
pub fn init(allowed: []const u8) ?Self {
30+
var nameIter = Self{ .allowedChars = allowed };
31+
32+
for (0..6) |i| {
33+
while (!in(nameIter.name[i], allowed)) {
34+
nameIter.prefferedPos[i] += 1;
35+
if (nameIter.prefferedPos[i] >= prefferedChars[i].len) break;
36+
nameIter.name[i] = prefferedChars[i][nameIter.prefferedPos[i]];
37+
}
38+
39+
while (!in(nameIter.name[i], allowed)) {
40+
nameIter.allowedPos[i] += 1;
41+
if (nameIter.allowedPos[i] >= allowed.len) return null;
42+
nameIter.name[i] = allowed[nameIter.allowedPos[i]];
43+
}
44+
}
45+
return nameIter;
46+
}
47+
48+
pub fn current(self: *Self) []const u8 {
49+
return self.name[0..self.nameLen];
50+
}
51+
52+
pub fn next(self: *Self) ?[]const u8 {
53+
if (self.fail()) return null;
54+
if (self.charId < prefferedChars.len and self.prefferedPos[self.charId] < prefferedChars[self.charId].len) {
55+
self.name[self.charId] = prefferedChars[self.charId][self.prefferedPos[self.charId]]; // TO DO omit unallowed characters
56+
self.prefferedPos[self.charId] += 1;
57+
self.charId = 6;
58+
} else if (self.allowedPos[self.charId] < self.allowedChars.len) {
59+
self.nameLen = self.charId + 1;
60+
self.name[self.charId] = self.allowedChars[self.allowedPos[self.charId]];
61+
self.allowedPos[self.charId] += 1;
62+
} else {
63+
self.charId += 1;
64+
if (self.charId >= self.name.len) {
65+
self.charId = 0;
66+
self.allowedPos[6] = 0;
67+
self.allowedPos[7] = 0;
68+
self.allowedPos[8] = 0;
69+
self.nameLen = 6;
70+
}
71+
return self.next();
72+
}
73+
74+
return self.current();
75+
}

src/client.zig

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ const Message = @import("message.zig");
66
const game = @import("game.zig");
77
const Game = game.Game;
88
const Unit = game.Unit;
9-
const Config = game.Config;
9+
const Config = @import("Config.zig");
1010
const coordOps = @import("coordinateOps.zig");
11+
const NameIterator = @import("NameIterator.zig");
1112

1213
const singleReadSize = 50;
1314

@@ -17,7 +18,7 @@ pub const Client = struct {
1718
stream: Stream,
1819
state: State,
1920
game: ?Game = null,
20-
name: [7]u8 = [7]u8{ 'z', 'i', 'g', 'b', 'o', 't', '!' },
21+
nameIter: NameIterator = undefined,
2122

2223
/// sets up TCP connection
2324
/// after init .game is still null, .game will be initialized in .parse() if client recieves c message from server
@@ -79,29 +80,34 @@ pub const Client = struct {
7980
};
8081

8182
self.game = try Game.init(c, allocator);
83+
84+
self.nameIter = NameIterator.init(self.game.?.allowedNameCharacters).?;
85+
8286
try self.send("n");
83-
try self.send(&(self.name));
87+
try self.send(self.nameIter.current());
88+
print("requested name: {s}\n", .{self.nameIter.current()});
8489
try self.send("\n");
8590
}
8691
},
8792
@intFromEnum(Message.Type.yes) => {
8893
if (self.state == State.Connected) {
8994
self.state = State.Ready;
90-
try std.io.getStdOut().writer().print("named self: {s}\njoining...\n", .{self.name});
95+
try std.io.getStdOut().writer().print("named self: {s}\njoining...\n", .{self.nameIter.current()});
9196
try self.send("j\n");
9297
}
9398
},
9499
@intFromEnum(Message.Type.no) => {
95100
if (self.state == State.Connected) {
96-
const last = self.name.len - 1;
97-
if (self.name[last] == '~') {
101+
const newName = self.nameIter.next();
102+
if (newName) |name| {
103+
try self.send("n");
104+
try self.send(name);
105+
try self.send("\n");
106+
print("requested name: {s}\n", .{name});
107+
} else {
98108
try std.io.getStdOut().writer().print("unable to set a name\nlook into mini-rts-server .config file and make sure characters z, i, g, b, o, t are set as valid name characters or contact your mini-rts-server administrator\nalso make sure not too many zigbots are playing at the same time\n", .{});
99109
return error.UnableToNameSelf;
100110
}
101-
self.name[last] += 1;
102-
try self.send("n");
103-
try self.send(&self.name);
104-
try self.send("\n");
105111
}
106112
},
107113
@intFromEnum(Message.Type.queue) => {
@@ -169,11 +175,11 @@ pub const Client = struct {
169175
const x = try std.fmt.parseUnsigned(u32, it.next().?, 10);
170176
const y = try std.fmt.parseUnsigned(u32, it.next().?, 10);
171177

172-
try self.game.?.newUnit(playerName, Unit{ .id = id, .x = x, .y = y, .hp = 100 });
178+
try self.game.?.newUnit(playerName, Unit{ .id = id, .x = x, .y = y, .hp = self.game.?.unitHp });
173179
},
174180
@intFromEnum(Message.Type.leave) => {
175181
const playerName = buff[1..]; // player name
176-
if (std.mem.eql(u8, playerName, &self.name)) {
182+
if (std.mem.eql(u8, playerName, self.nameIter.current())) {
177183
try std.io.getStdOut().writer().print("lost all units\nrejoining...\n", .{});
178184
self.game.?.clear();
179185
self.state = State.Ready;
@@ -191,7 +197,7 @@ pub const Client = struct {
191197
},
192198
@intFromEnum(Message.Type.win) => {
193199
const playerName = buff[1..]; // player name
194-
std.debug.assert(std.mem.eql(u8, playerName, &self.name));
200+
std.debug.assert(std.mem.eql(u8, playerName, self.nameIter.current()));
195201
try std.io.getStdOut().writer().print("won the game\nrejoining...\n", .{});
196202
self.game.?.clear();
197203
self.state = State.Ready;
@@ -236,7 +242,7 @@ pub const Client = struct {
236242
try self.game.?.newPlayer(buff[1..]);
237243
},
238244
@intFromEnum(Message.Type.tick) => {
239-
const player = self.game.?.findPlayer(&self.name).?;
245+
const player = self.game.?.findPlayer(self.nameIter.current()).?;
240246
var it = player.units.valueIterator();
241247
while (it.next()) |unit| {
242248
const max_len = 10; // TO DO figure out max_len from config sent by server
@@ -273,6 +279,7 @@ pub const Client = struct {
273279

274280
pub fn deinit(self: *Client) void {
275281
self.stream.close();
282+
self.game.?.deinit();
276283
}
277284
};
278285

src/game.zig

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const testing = std.testing;
33
const print = std.debug.print;
44
const distance = @import("coordinateOps.zig").distance;
55
const coords = @import("coordinateOps.zig").coords;
6+
const Config = @import("Config.zig");
67

78
pub const Unit = struct {
89
id: u32 = undefined,
@@ -118,19 +119,6 @@ pub const Player = struct {
118119
}
119120
};
120121

121-
pub const Config = struct {
122-
millis: u32,
123-
maxPlayers: u32,
124-
boardX: u32,
125-
boardY: u32,
126-
startResources: u32,
127-
unitsToWin: u32,
128-
resourceHp: u32,
129-
unitHp: u32,
130-
unitDamage: u32,
131-
allowedNameCharacters: []const u8,
132-
};
133-
134122
pub const Game = struct {
135123
board: Board,
136124
players: std.ArrayList(*Player),
@@ -275,6 +263,7 @@ pub const Game = struct {
275263
self.units.deinit();
276264

277265
self.board.deinit();
266+
self.allocator.free(self.allowedNameCharacters);
278267
}
279268
};
280269

0 commit comments

Comments
 (0)