ID:78708
 
Keywords: bgc, chess, development
So I finally decided to get back around to chess, since my desire to work on other projects has all but burned out from a combination of user apathy and my own feelings of toiling for little reward. Chess seemed to have a devout following in its heyday, and with any luck I can bring that back again. Why I ever abandoned it to begin with is a mystery.

As mentioned on Chess's hub page, I decided to abandon simply editing the existing code. In addition to just being broken at a basic level, I'm attempting to add features not found in the original incarnation, such as a chatting game-type channel system that will allow many simultaneous games to be going on at once. Presently, the goal is to support one game per channel, but in the process of making it, I may decide to go for multiple games in a single channel. I should probably figure this one out soon before I get too deep in development. What do you lot think?

What I'm presently planning to do (which should save me everything but development time) is make a single game board on the map, then use /images to display the piece locations, timer, or turn indicator as necessary to the people residing in that room and watching that particular game. I've not yet investigated just how feasible it actually is, which is probably why I'm subconsciously limiting myself to the channel aspects.

For the most part, what I've managed to do today is form a basic chatting game framework around the actual chess game. I think I'll flesh out that aspect before going into the game itself.

Here's the complete code as it stands, untested. I likely won't make this an open source project, so the following is more an indication of progress.

#define OUTPUT "main_window.default_output"

client
var
chess/table/location = null
challengeable = 1
verb
Challenge()
set desc = "Challenge any unoccupied online player to a match."
var/clients[0]
for(var/client/c)
if(c != src && c.challengeable && (!istype(c.location.game) || (c.location.game.black != c && c.location.game.white != c))) clients += c
if(clients.len)
var/client/c = input(src,"Who will you challenge? If accepted, you and your opponent will be moved to a new room if necessary.","Challenge") as null|anything in clients
if(istype(c))
if(c.challengeable && (!istype(c.location.game) || (c.location.game.black != c && c.location.game.white != c)))
var/chess/table/r = null
//discover/create a room
if(!istype(src.location.game)) r = src.location
else if(!istype(c.location.game)) r = c.location
else r = new(src.key,"Temporary room [world.realtime]")
r.join(src,c)
//get the game rolling
r.game = new(src,c)
r.game.start()
else alert(src,"[c.key]'s status changed while you were selecting an opponent, and is no longer challengeable.","Challenge")
else alert(src,"There is no one online or available to challenge.","Challenge")
Create_room()
set desc = "Create a chess room."
var/n = input(src,"What will you name the room?","Create room") as null|text
if(n && length(ckey(n)))
var/chess/table/r = new(src.key,n)
r.join(src)
Join_room()
set desc = "Join a chess room as a spectator."
var/rooms[0]
for(var/chess/table/t)
if(istype(t) && src.location != t && !(src.key in t.banned) && (!t.private || (src.key in t.invited))) rooms += t
if(rooms.len)
var/chess/table/r = input(src,"Which room will you join?","Join room") as null|anything in rooms
if(istype(r)) r.join(src)
else alert(src,"There are no joinable rooms. Why not make one?","Join room")
Toggle_challenges()
set desc = "Toggle the ability for other players to challenge you. You will still be able to join games of your own volition."
src.challengeable = !src.challengeable
src << output("Challenges are [src.challengeable ? "en" : "dis"]abled.",OUTPUT)

chess
game
New(w,b)
src.white = w
src.black = b
proc
start()
//FINISH
var
client
black = null
white = null
list/graphics = null
verb
Offer_draw()
set category = "Game"
set desc = "Offer to end the game. This results in a draw."
Play_as_black()
set category = "Game"
set desc = "Sit down at this board as black. Once there is a pair of players sitting, the game begins."
Play_as_white()
set category = "Game"
set desc = "Sit down at this board as white. Once there is a pair of players sitting, the game begins."
Resign()
set category = "Game"
set desc = "End this game, marking it a loss by forfeit on your part."
Rotate_board()
set category = "Game"
set desc = "Rotate the game board 90 degrees."
table
New(c,n)
src.dont_delete_me = src
src.creator = c
src.name = n
proc
add_ban(key)
if(isnull(src.banned)) src.banned = new /list
src.banned += key
add_client()
for(var/i=1;i<=args.len;i++)
var/client/c = args[i]
if(istype(c) && (isnull(src.clients) || !(c in src.clients)))
if(isnull(src.clients)) src.clients = new /list
src.clients += c
add_invite(key)
if(isnull(src.invited)) src.invited = new /list
src.invited += key
join()
for(var/i=1;i<=args.len;i++)
var/client/c = args[i]
if(istype(c))
if(!src.private || (!isnull(src.invited) && (c.key in src.invited)))
if(istype(c.location)) c.location.leave(c)
src.add_client(c)
c.location = src
//if(src.game) c.images.Add(src.game.graphics)
src.report("[c.key] has joined.")
leave()
for(var/i=1;i<=args.len;i++)
var/client/c = args[i]
if(istype(c))
if(c.location == src)
//if(src.game) c.images.Remove(src.game.graphics)
src.clients << output("[c.key] has left.",OUTPUT)
src.remove_client(c)
remove_ban()
if(!isnull(src.banned))
src.banned.Remove(args)
if(!src.banned.len) src.banned = null
remove_client()
if(!isnull(src.clients))
src.clients.Remove(args)
if(!src.clients.len) src.clients = null
remove_invite()
if(!isnull(src.invited))
src.invited.Remove(args)
if(!src.invited.len) src.invited = null
report(msg,control=OUTPUT)
src.clients << output(msg,control)
var
chess
game/game = null
table/dont_delete_me = null
list
banned = null
clients = null
invited = null
creator = ""
name = ""
private = 0
verb
Ban()
set category = "Room"
set desc = "Remove a player from the room."
var/client/c = usr
if(istype(c) && istype(c.location))
if(c.location.clients.len > 1)
var
list/players = (c.location.clients-c)
client/k = input(c,"Who do you want to ban?","Room ban") as null|anything in players
if(istype(k))
c.location.report("[c.key] banned [k.key] from the room.")
c.location.add_ban(k.key)
c.location.remove_invite(k.key)
c.location.leave(k)
else alert(c,"There is no one to ban from this room.","Room ban")
Disinvite()
set category = "Room"
set desc = "Rescind an invitation to your room."
var/client/c = usr
if(istype(c) && istype(c.location))
if(!isnull(c.location.invited))
var/k = input(c,"Remove whose invitation?","Room disinvite") as null|anything in c.location.invited
if(!isnull(k))
c.location.remove_invite(k)
c.location.report("[c.ckey] disinvited [k].")
else alert(c,"There are no standing invitations to this room.","Room disinvite")
Invite()
set category = "Room"
set desc = "Invite a player to the room. Players invited remain able to rejoin the room at any time until disinvited."
var/client/c = usr
if(istype(c) && istype(c.location))
var/players[0]
for(var/client/k)
if(k.location != c.location && !(k.key in c.location.banned)) players += k
if(players.len)
var/client/k = input(c,"Who will you invite? Those currently playing a game will be notified of the invite, but not prompted to join.","Room invite") as null|anything in players
if(istype(k))
c.location.add_invite(k.key)
c.location.report("[c.key] invited [k.key].")
k << output("You have been invited [c.key != c.location.creator ? "by [c.key] " : ""]to [c.location.creator]'s room, [c.location.name].",OUTPUT)
if((!istype(k.location) || (k.location.game.black != k && k.location.game.white != k)) && alert(k,"You have been invited [c.key != c.location.creator ? "by [c.key] " : ""]to [c.location.creator]'s room, [c.location.name]. Join?","Room invite","No","Yes")) c.location.join(k)
else alert(c,"There is no one to invite.","Room invite")
Name()
set category = "Room"
set desc = "Change this room's name."
var/client/c = usr
if(istype(c) && istype(c.location))
var/n = input(c,"What will you name this room?","Room name",c.location.name) as null|text
if(!isnull(n) && length(ckey(n)))
for(var/chess/table/t)
if(ckey(t.name) == ckey(n))
alert(c,"You cannot rename this room to [n] because it is canonically identical to [t.creator]'s room, [t.name].","Room name")
return
c.location.report("Room was renamed from \"[c.location.name]\" to \"[n]\".")
c.location.name = n
Privacy()
set category = "Room"
set desc = "Toggle this room's privacy setting. Private rooms can be joined by invite only."
var/client/c = usr
if(istype(c) && istype(c.location))
c.location.private = !c.location.private
c.location.report("Room set to [c.location.private ? "private" : "public"].")
Unban()
set category = "Room"
set desc = "Unban a player from the room."
var/client/c = usr
if(istype(c) && istype(c.location))
if(!isnull(c.location.banned))
var/k = input(c,"Remove which ban?","Room unban") as null|anything in c.location.banned
if(!isnull(k))
c.location.remove_ban(k)
c.location.report("[c.ckey] unbanned [k] from the room.")
else alert(c,"There are no standing bans from this room.","Room unban")
*steals the source and makes Chess Ultimate Revised: Revenge of the Pawn*
Noes, 45 minutes of my life squandered =<
The "Front line general" medal is impossible to achieve.

You should instead have to claim X enemy pieces with your king.
I've been awake too long swilling coffee, and that was just bad sleepy grammar on my part. The medal is earned by having your king involved in the checkmate somehow (e.g., preventing the capture of the mating piece, blocking off escape squares).

SuperAntx wrote:
The "Front line general" medal is impossible to achieve.

You should instead have to claim X enemy pieces with your king.

Crap load of Runtime Errors.
Now it's a little overkill, the wording looks fine without the E.G. stuff.

You can change the wording a little on "How you like them apples?" and "In due time..." to remove the parentheses.

"Win a game having lost less than or half as many pieces as your opponent."

"Win a game having lost at least twice as many pieces as your opponent."
:D
Howey wrote:
Crap load of Runtime Errors.

I never tested the code until tonight, though I didn't get any runtimes; it just didn't do anything until I changed all the usrs to usr.clients.


SuperAntx wrote:
Now it's a little overkill, the wording looks fine without the E.G. stuff.

You can change the wording a little on "How you like them apples?" and "In due time..." to remove the parentheses.

"Win a game having lost less than or half as many pieces as your opponent."

"Win a game having lost at least twice as many pieces as your opponent."

I'm too used to making explanatory texts for Icon Ultima, and I sometimes don't remember that chess won't be used by the same group of people, so I could probably remove some of those parenthesized explanations. What you suggest for "How you like them apples?" sounds like you can earn it just by having lost fewer pieces without any amount qualifier, though.