I have just received a communication from someone (unknown to me) via LinkedIn, asking about a computer program that I wrote (and continually revised) throughout the 1980s that solved the '8-puzzle'. I replied that I would have to get into my time machine and set it to return 34 years, but first I'll retrieve whatever shreds of memory I can find for the blog.
I came across this puzzle in a book written by David Levy; looking at the list of publications on his wiki page, this was probably 'Computer Gamesmanship: Elements of Intelligent Game Design' , published in the early 80s. One has to remember that I first 'met' a computer at the end of 1982: this was a teletype connected to a phone line that was connected to a PDP-11 computer about 20 miles away. I also had absolutely no background in programming, so this book talked about topics that were far above my ability. The 8-puzzle problem served as an introduction to all kinds of topics in computer science: how to draw a grid on a VT-100 screen, how to get direct input, how to check for legal moves, linked lists, hash tables ... there's a lot in there.
I wish I had access to these web pages back in the day instead of having to stumble in the dark, teaching myself all kinds of techniques. All I had were a few pages in Levy's book and another book about data structures in Pascal, instead of detailed guides.
My program had two modes: user and computer. First the computer would create a random initial configuration, then the user would be given the opportunity to solve the problem, whilst the computer counted how many moves the user required. For my program, this mode taught me about user interface: how to react to user input and how to change the display depending on the input.
But it was the second mode that was the more interesting: 'teaching' the computer how to solve the puzzle. Levy wrote about the 'minimax' algorithm, but it wasn't until one day I was in the computer science library of Bar Ilan university that I found out what this was. I imagine that I was doing some reserve army service in the lab at Tel Hashomer hospital, as the university was within walking distance (don't forget that I was/am a good walker; this was probably 2 km away). I acted like I had the right to access books and journals, and no one asked me who I was.
Every few months I would have a new idea as to how I could improve the evaluation function of the current configuration (basically, how far the current configuration is from the goal) in order to figure out what the next move should be. I also stored the various configurations for two reasons: I wanted to prevent the computer getting into a loop, and I wanted to look at the configurations myself to see how I would have acted. I remember now that I had a standard configuration that took me something like 37 moves to solve; any program version that took more moves needed to be improved. I also wanted to surprise myself and see whether the computer could solve this test configuration in fewer moves; after all, I'm no expert in this puzzle, and so it would be quite possible that the computer could beat me.
function evaluate (var p:square): integer; var i, tmp: integer; ch: char; blank: boolean; begin tmp:= 0; i:= 0; while i < 9 do begin i:= i + 1; ch:= p[i]; blank:= ch = ' '; if not blank then tmp:= tmp + table[(i-1)*9 + ord(ch) - zero] else tmp:= tmp + table[i*9]; if blank then if i <> 5 then tmp:= tmp + 2 else else case i of 5:; 2,4,6,8: if p[5] <> ' ' then if (p[preint[i]] <> prech[ch]) and (ch <> prech[p[5]]) then tmp:= tmp + 5 else else if p[preint[i]] <> prech[ch] then tmp:= tmp + 5; 1,3,7,9: if p[preint[i]] <> prech[ch] then tmp:= tmp + 3 end end; evaluate:= tmp end { evaluate };
No comments:
Post a Comment