Jump to content

Andrew Davie

  • Content Count

  • Joined

  • Last visited

  • Days Won


Andrew Davie last won the day on November 6 2019

Andrew Davie had the most liked content!

Community Reputation

2,182 Excellent


About Andrew Davie

  • Rank
    River Patroller

Profile Information

  • Custom Status
    Grumpy wise old wizard
  • Gender
  • Location

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I spotted this chess "computer" in the Falken video from the movie War Games (1983). What a hoot.
  2. Thanks, I'm not too concerned about boundary conditions at this stage. Basically you won't be ABLE to kill off all the computer pieces when it's all working, because you can never actually capture a king. There are a few things like you report - I'll track them down one by one. Basically I'm making a few assumptions for the extra speed. Stuff like you will ALWAYS find a piece to move, for example.
  3. Having just squashed a tricky bug related to castling, I thought I'd post a binary before embarking on the next thing. I have various "flags" attached to pieces, that give information about the piece. Things like colour, if the piece is en-passant capturable, if the piece has moved, and if the piece is castling. Well, normal castling was working fine, but if I moved the king one square instead of two... crash. I found that in the two-square case, the "castle" flag was set (correctly) and the code went and looked for and moved the appropriate rook. But in the one-square case, the "castle" flag was ALSO set (incorrectly). And yet, there was only one place in the code where that flag was set - when generating a two-square move for a king to castle. It took quite some time to find. What was happening was that when you clicked on a square, the code grabbed the piece information from the move list (correctly). You can't grab it from the board, because you need those extra flags. Basically it found the "from" square in the movelist. But.. but... in the case of castling, yes the from-square gives you "king" but actually there are king moves WITH and king moves WITHOUT the "castle" flag. And it just so happens that every time the code was getting the king/flag WITH the castle flag set. In other words, several moves for the king from that start square, but only one of them has castle flag set. So, the solution was -- once the "to" square has been selected, then search the movelist for the from AND to square, and get the piece/flags for that move. And continue. That solved my little problem, but took a while to find and a bit of head scratching. I've also done some thinking about that "castling in check" stuff. My thinking so far... rather than make all the moves and look at all replies to all moves, what I can do is generate moves for the opponent up-front (even though it's not the opponent turn). Then I can mark in an array all squares to which opposition pieces can move to. That gives "all the squares being attacked". We should not allow MY king to be on an attacked square, OR the squares king moves across to be an attacked square. So this will remove the need to do a move-by-move move/response and I junk that earlier 1000 move estimate for this particular issue. I may get that sorted before moving onto other stuff. Here's a binary... have a play with castling, if you want... I think it should be pretty solid. Other than the "castle while in check" bit. chess_20200216.bin
  4. Although I have quite a bit of work to do still on the UI, I'm starting to think about the AI/search. In particular, reducing that 33-fold branching factor down as much as possible. Of course, alpha-beta pruning will significantly reduce it with a well-sorted move list. The idea being to prune as much as possible by having moves that are likely to lead to pruning early. In other words, sorting the movelist before going further down the tree. I've had a good think about this, and I think/suspect that the best way to do this sort might be to actually do a short traversal of the tree! In other words, let's say I'm doing a 6-ply search. First I generate the moves (ply 0). Now the job would be to sort them. Instead (or as well as) heuristics like put captures first, refutation moves (found in previous moves) first... etc., how about I just do a (sub/recursive) tree search to a lower depth for each move. That is, look (say) 3-plys ahead. That would then allow me to rank the moves according to the evaluation routine 3-plys lower. Of course I'm adding extra tree-searching but it's only a 3-ply cost, and by spending that "3 ply of time", I now have lots more information about how good each move is. In fact, not only can I sort the moves more reliably, I could even consider just choosing (say) the first 7 moves (because they're nominally "the best 7" now) and discarding all the rest. It will be really interesting to see how (nested) shorter tree searching embedded within the alpha-beta search... will affect the speed.
  5. There are "timers" on the machine which when set to a value will reliably count-down to zero. You can read a register to find out when they reach zero. So the principle is to set the timer at the start of your vblank processing time, for example, then do whatever you want - and after it is finished you just wait for the timer to reach zero. You are guaranteed to have a "stable" frame if you use timers, and if your "whatever your want" stuff executes quickly enough. Here's sample usage... ; END OF VISIBLE SCREEN ; HERE'S SOME TIME TO DO STUFF lda #38 ; or whatever time you allocate for this sta TIM64T ; in 64-cycle chunks ; do some stuff here ; as long as it takes at most 38*64 cycles, we're good Waitforit bit TIMINT bpl Waitforit ; wait for timer to reach zero jmp .StartFrame ALSO, rather than just waiting for the timer to reach 0 (via the "bit" instruction), you can actually ask how much time is left... lda INTIM cmp #SAFETIME bcc .skip ; not enough time to do the next bit ; do some stuff here that takes < SAFETIME*64 cycles .skip This allows you to do complex "multitasking" if you have a scheduler that simply checks if there's enough time to do a task, and fires off a call to the task if there is. You need, of course, to calculate the time requirements for a task by cycle-counting (or even easier now with the new stella timing capability) and making sure there's enough time (6502 cycles the task takes/64) for the task. There are other timers other than TIM64T (TIM1T, TIM8T, T1024T) but I have only used the TIM64T myself.
  6. Castling for humans is now working. Video shows first king-side castle, and then queen-side castle. It takes a few moves to get all the pieces "out of the way" so that the castle move can be done. Note, the game correctly disallows castling if you have moved the king or the relevant rook, but does not at this stage prevent you castling if your king or the squares he crosses/occupies is in check. That's in the rules, you know! That will come later, when I put in some code to remove illegal moves from the movelist at the start of human moves. I've started it already, but it's going to be tricky to fit into "leave the screen on while you do it" bit. I do, however, want to try to get that working because I expect a human vs. human game NOT to blank the screen at any time. We shall see - it's going to be a challenge because to do the check... checks, I have to do all the available moves, and in respond to all of those generate all the opponent moves. Could be up to 1000 moves generated at some points and currently I'm only generating moves for a single piece per frame. So that would be, I guess, about 16 seconds at the start of interaction while it figures which are legal or not. Now that's obviously not on, so... as I said, a challenge. I'm sure I'll figure something out, but not quite sure how. Maybe I just leave the move there, let the human make it but then say "hey, sorry... illegal because... check". I'll get to that later, but next I'm going to work on the en-passant capture for human. Computer version is already working, I think. After that, pawn promotion for human and how that integrates with the UI humanCastle.mp4
  7. I took a bit of a diversion to test out an idea. The video shows my BYO demo, but the source image has been adjusted so that the pixels are 4x width in the horizontal direction. If you ignore the single pixel stippling (which is a result of the BYO ICC dithering), the point of this test is to see if it would be possible to have good colours with full ICC for playfield graphics for the chess program. Instead of sprites, as shown here, I would be using PF graphics. That's why the pixels are 4x wide. The result would be full-screen, just like the existing display. It would be a bit of a major pain changing to this - and there would be significant ROM/RAM and speed overheads. But, for posterity anyway, here's the result. I get triple the vertical resolution going this way, and I can have colours on all lines (for example, the blue squares are now all-blue instead of blue every third scanline). There's a bit of a shimmer from the ICC technique, so a bit of give and take. I think the contrast in the black/white pieces is significantly improved. I don't know if I'll use this... but here it is anyway. testICC.mp4
  8. "Ha ha ha" "Ha! You have fallen for my trap!" "Mate in 236 moves..." "I saw that!" "Puny human" "Don't look a gift knight in the mouth" "We all learn from our mistakes: you have infinite improvement capability" "You have a good memory for bad openings" "You play like a human" "You play like a computer" "I was playing that one blindfolded" "Atari! ..... whoops..... wrong game... Check!" "If i had feet, I'd be kicking you under the table right now" I welcome comments/additions!
  9. I love the idea of the computer being a "dirty" player by talking to distract. There are some online suggestions as to what to say. I might put in the occasional computer laugh when you move, or lose a piece. Could be lots of fun coming up with stuff.
  10. Ok, technically you don't need the ,x. .. right? You could hardwire it so access to INPT0 did the job of reading both.
  11. Yes, I was just trying to point out a simple access to the address would be sufficient and just dropped off the "stx DWRITE" to make the point. Essentially this would be 3x quicker than the original 6507 implementation - 3 cycles instead of 9.
  12. Aerlan's comments were mostly correct - and it was great to see someone who had a bit of knowledge about the subject talking about the game. You covered a few things, but one thing I think you missed as a limitation was the sheer lack of processing power. 1.19MHz doesn't do much in the world of chess. This is going to be a pretty stock-standard chess algorithm - no way will it be able to do neural nets like Alpha Zero, for example. I kind of like my "completely random" AI because, rarely, but every once in a while.. a long while... it will play the absolute best chess game ever played and be completely unbeatable.
  13. I'm not familiar with ARM, of course, but couldn't you improve this by simply doing the "ldx INPT0" and having the ARM detect the address being the paddle and do everything from that point?
  14. Ha. I think I'm onto something here.
  • Create New...