Jump to content

Vorticon

Members
  • Content Count

    4,687
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by Vorticon


  1. 1207045296_PhoenixChessTest.jpg.57e49ba355cad2681628b3eeaa929988.jpg

     

    It's alive! Ok still very dim-witted, but alive... :lol:

    This is just a test window with the computer playing against itself, and it just nearly checkmated itself in 3 moves! Still having trouble detecting check mate situations as well as getting out of check threats. This test pretty much exercises the entire code base, and at least I know the piece movements are correct and that the board is being updated accurately. I have so far only implemented basic pawn strategies, general piece capture incentives  and king check maximization, but everything else is remains very much random movement.

    • Like 4
    • Thanks 1

  2. On 8/26/2020 at 8:27 AM, dhe said:

    Vorticon,
    If you can let me know the upgrade procedure, that would be most helpful.
    Thanks,
    Dan

    Hi Dan.

    1. Download the attached zip file and extract it somewhere.
    2. Start up your Arduino IDE, connect the Arduino Uno making sure you've got the proper COM port configured in the IDE
    3. Load the src.ino file from the src directory in the file you just downloaded.
    4. Press CTRL-U and it will compile and transfer the binary to the Arduino. You might get a low memory message which you can safely ignore. If you get an error pointing at the DS32xx line, you will need to go into the IDE under under Tools --> Manage Libraries and search for the appropriate DS32xx file and install it. Restart the IDE and the process should work now.
    5. Install a FAT32 formatted SD card into the Arduino SD shield, connect the Arduino to your CC40, power it up first then the CC40 and off you go :)

    Hopefully this helps.

     

    HEXTIr-libmerge.zip

    • Thanks 1

  3. 7 hours ago, brain said:

    OK, I think I have removed the last of the Arduino specific code fragments from the IDE build in branch libmerge.  I tested with my Arduino UNO in native and IDE and it worked fine.  Vorticon, if you could try it, I'd appreciate hearing if it works. 

     

    Jim

    Success! Works perfectly and passes the FOPSTEST. Nicely done :)

    • Like 1

  4. 3 hours ago, sometimes99er said:

    The headache
     
    Since part of some "reopening of society", I've been around, including acupuncture, MR- and CT-scans. Next up is a neurologist in a few days. Have had this thing for a year now.

    Sounds like you've ruled out the most serious etiologies (anatomical malformations, increased intra-cranial pressure, brain turmors, glaucoma, hypertension). What remains is more difficult to tackle and multi-factorial. Have you seen an endocrinologist to rule out hypermetabolic states like thyroid or adrenal issues? How about a glucose fasting test? Have you had an EEG?

    Barring any apparent organic causes, I would certainly consider an elimination diet looking for food triggers. A dietitian can be of great help here.

    I really do hope you get to the bottom of this and get better. 

    • Like 2

  5. 12 hours ago, jedimatt42 said:

     

    Screenshot_082820_055420_PM.thumb.jpg.2fa810e2605efa292d29830c5002b9c4.jpg

     

    Yep, so I pressed backspace after the 'o' in hello, and then sent the output to hexdump... the backspace took, the 'o' is gone, but the display decoding is all buggered. So.. not sure how to capture what is being sent, other than turning on byte level tracing of TIPI messages... so... maybe someday...  I'd rather finish working the API for ForceCommand, which encapsulates the terminal handling code, and fix it there, and then rebuild a working telnet on top of that API... 

    The problem is only in the main rpi shell (I assume bash). Once you are in an application, the latter responds correctly to the backspace code being sent. 

    • Thanks 1

  6. 19 hours ago, wolhess said:

    on the Ti I use only the back arrow FCTN+S.

    I tried FCTN-S and CTRL-Q and while they do erase characters, the cursor itself moves to the right instead of to the left. It took me a while to realize that :lol:

    That's an old behavior legacy Basic's... Is there a way to configure the tipi telnet to move the cursor to the left when backspacing?

    • Like 1

  7. On 8/18/2020 at 1:12 AM, brain said:

    Manfred pushed some updates into the sreid_mods branch to hopefully handle inputting data from HEXTir.  I'd appreciate folks trying it out.

     

    Jim

     

    Excellent news! I'll test it out. With that issue out of the way, I believe the storage problem for the CC40 is now resolved. 

    I am very grateful for the work by all involved. The lack of storage for the CC40 has been a vexing situation for decades...

    Time to start thinking about new programs for it :) 


  8. So there is not true byte type as in Turbo Pascal in UCSD, but you can essentially create one.

    8 hours ago, BillG said:

    Sure it does.  Use array of char and ord() to "convert" to integer.

    Clever! Did not think of that :)

    1 hour ago, apersson850 said:

    You have to declare it as

     

    type

      bytes = 0..255;

      bytearray = packed array[0..88] of bytes;

     

    However, the system's procedures to handle packed arrays will usually cost more than the normal indexing. But in this special case, the compiler is smart enough to realize that this is a byte, not a value with some odd number of bits. Thus finding the correct value will generate one p-code, LDB (load byte). This is clearly the most efficient way to address an array with byte-size values.

     

    Addressing arrays in general allows for any size of each element. The p-code IXA (index array) handles the address calculation. For an array of integers, the word index into the array is the same as the index itself. But since IXA is a general array index calculator, it will multiply (using assembly instruction MPY) the index you supply with the size of each element (in this case 1), then shift the result left one bit, then add this to the array base, to find the memory address of the desired value. This address is left on the stack, where it's picked up by SIND (short index and load), which returns the actual value.

     

    So in this case, using the array as suggested above in this post uses about half the amount of instructions (assembly) for each access, and avoids the long MPY instruction altogether. Thus it's both faster and saves memory, even compared to indexing the integers from 11 to 88.

    Using a different base than zero, on the other hand, will generate two additional instructions for each access. One to load the base index, the other to do an integer subtraction. Which is equivalent to wasting all you gained from using a byte sized array.

    However, running with range checking enabled will cost you more than the longer of the two alternatives for each access, and that's regardless of how you make up the array itself. Once you know your code is working, and you don't get any index out of range errors, you can turn off range checking with the (*$R-*) compiler directive.

     

    To summarize, using a packed array of bytes and turning range checking off will reduce the time to access each element to about 1/5 of what you do now.

    You can easily optimize the code on the Pascal level, without losing readability, but it takes you are well aware of what the compiler will do with your code, and which p-codes the interpreter runs in the most efficient manner.

    This is truly very valuable information and extremely relevant to my project because it's all about accessing and handling arrays. It should be fairly trivial to make the changes since only the declarations change, not the handling of the arrays. I'm going to run some tests and see what kind of speed gains I get.

     

    • Like 2

  9. 9 minutes ago, BillG said:

    What kind of information are you keeping in that array?  Namely, will bytes work rather than integers?

     

    It may be more efficient for the compiler to generate access to bytes in the array by avoiding a left shift of the index to address integers.

    Just integers 1-16. I don't believe UCSD pascal supports byte types though.


  10. Ah ok makes sense. The array tmpboard, while declared as [11..88] of integer, only has a subset of valid locations within that range specified in the validloc set. What threw me off was the fact that while I have multiple similar constructs throughout the code, I never previously had allowed the index i to go outside the 11..88 range, unlike this case, which is why I never got into trouble previously.

    Thanks for the clarification.

    PS: Execution error 1 (index out of range) has been the bane of my existence with this project. Absolutely a nightmare to debug in a large multi-unit project...

     


  11. I have a little puzzler I'd like perhaps some insight on. Can someone please tell me why the following code does not work 

    if turn>2 then
      begin
    	if ((i-11) in validloc) and
           (tmpboard[i-11]=6) then
          cscore:=cscore+30;
      end;	

    whereas if I reformat it as below the error goes away? Makes little sense to me as the inner begin/end pair should not be needed....

    if turn>2 then
      begin
        if ((i-11) in validloc) then
    	  begin
    		if (tmpboard[i-11]=6) then
    		  cscore:=cscore+30;
    	  end;
      end;	

    As a background, the index of the tmpboard array has a range of 11 to 88 which is contained in the validloc set. So if i-11 goes out of range, then the second half of the if statement in the first code snippet should not get executed, and yet it does... 


  12. There are no integral graphics commands to UCSD Pascal and the TI implementation does not include things like GCHAR, HCHAR or VCHAR, so you will have to roll your own.

    The initial chess position is stored in the chessboard array with each piece having an assigned numerical value: King=1, Queen=2, Rook=3, Knight=4, Bishop=5 and Pawn=6 for white. Add 10 to the value for black. When generating a move, the array contents are scanned in order to locate pieces and make calculations, and the array is updated with each turn. Temporary mirror arrays are also created to test potential moves against the evaluation function before committing to any particular response.

    The computer actually pre-calculates a limited set of player responses during its position evaluation depending on the ply depth and if the player indeed plays these moves, then the response time is immediate since no evaluation is required. However, since the evaluation function attempts to maximize the computer's score while minimizing the player's, I'm not sure if it will frequently succeed in predicting a good player's move :) We shall see!

    Given the complexities I have encountered, I am utterly amazed how some brilliant programmers have managed to create complete chess programs under 1K (in assembly)... They may not play well, but still!

    • Like 3

  13. 2 hours ago, 1980gamer said:

    I stink at this game, but know the rules... I think? Castling is not in my playbook... I have had people do it to me... I have to assume they are not cheating!  LOL

    Being as only 1 piece moves per turn, do you have to score each piece on the board each time?

     

    Can that scan be reduced?  certainly some pieces will not change? But again, I do not know this game.  I am here for the process. 

    I need to learn recursion for a project or some other algorithm and this seems much easier in other languages than TI Extended Basic!

     

    However, you may spark something in me the figure it out. 

     

    Another thought, early in the game when ALL pieces are still in play,  some cannot move.  Can you skip those pieces from the "scan"?

    The Knight would always be scanned I would think. But other non Pawns are locked to start. You could skip them maybe?

     

    Yeah, castling was a different challenge altogether :lol: Recursion definitely plays a big part in this program, something UCSD Pascal is quite capable of. 

    It's hard for a computer to figure out which pieces are blocked without checking each possibility unfortunately (see my previous post). And indeed, the first few moves are computed faster than subsequent ones because there are fewer valid movement options. 

    The main issue here is that UCSD Pascal is quite slow compared to say assembly or forth, but on the plus side it's a very easy language to work with and very structured which is important for complex projects like this one. As I stated before, this is more of an academic exercise than anything else :) 


  14. 2 hours ago, FarmerPotato said:

    Couldn't you work backwards from the king? That way you'd examine at most 2 rows and columns, 2 diagonals, 8 knight moves = 35 squares to see if eligible pieces can attack.

     

    What if you cached the squares that a piece can attack? thats 8 bytes for each piece. To test if any square is covered, make an 8 byte mask of squares to check, then test that against a bit field that each piece caches. Possible improvement: use a separate shape to test against a type of piece. Having matched a piece, you have to see if the piece is blocked from attacking. 

     

    The king in check search is actually incorporated into a broader potential piece capture routine and is just a secondary outcome. Each piece on the board goes through all its valid displacements, and if it hits the king then a check situation exists otherwise if it's an opposing piece then it's a potential capture. That routine creates a base score for any given position where the total material value of the pieces as well as the values of the pieces threatened by capture and any king checks are taken into account on both sides of the board then subtracted from each other. That base score will later be modified based on certain development criteria.

    As for the displacement scheme, the internal representation of the chessboard is designed in a way that each piece has a limited set of displacement deltas and not absolute displacements (stored in a matrix), which are added to its current position to generate all possible reachable positions. For example, the king and knight have 8 displacement deltas, whereas the rook and bishop have 28. The queen simply recycles the displacements deltas of the rook and bishop combined. In essence this scheme is kind of a mask. The chessboard is an array [11..88] of integer, and any final position (current position + displacement delta) that falls outside of that range or lands on a friendly piece is not valid. The displacement delta is repeated to create rays, a process which stops at an invalid position.

     

    Chessboard representation

     

    18 28 38 48 58 68 78 88

    17 27 37 47 57 67 77 87

    16 26 36 46 56 66 76 86

    15 25 35 45 55 65 75 85

    14 24 34 44 54 64 74 84

    13 23 33 43 53 63 73 83

    12 22 32 42 52 62 72 82

    11 21 31 41 51 61 71 81

     

    For example, the king displacement deltas starting straight forward and moving clockwise are 1,11,10,9,-1,-9,-10,-11 and these will work from any starting position on the board.

     

     

    • Like 1

  15. Figuring out when the king is in check as well as potential captures turned out to be computationally intensive. Basically for each board position sent for scoring, the computer cycles through all the pieces on the board, performs all possible displacements for each piece and checks if the end-square happens to be the king (taking into account the playing side of course) as well as any other potential captures and assigning a base score to the position. Sooo, response time just went from a little under 5 minutes to 9.5 minutes on the first level, and there is still a lot to do with the evaluation function. Oh boy...

    I have a feeling this is going to end up being an academic exercise at best 😛

×
×
  • Create New...