CS470/570  Artificial Intelligence

Program #1:  Fred Flintstone problem-solving
(a.k.a.  Warming up our Python mojo)

Overview: 

There's nothing intrinsically different or magical about AI programming; it's all just software...only it just happens to be specialized towards certain analytic orientations, algorithms, and problem-solving goals.   Well heck, you're all rock-star programmers, right?  So let's get that programming mojo warmed up with a little basic problem-solving challenge!

I'm calling this "Fred Flintstone problem-solving" because it's just that:  we know nothing at this early point in the course, so we can offer only completely off-the-cuff, uninformed, "naive" solving of a problem.  As we move forward, we'll soon develop a broader understanding of the intellectual "terrain" surrounding problems like these:  what we are really doing, what the alternative solution approaches in this terrain are, and how to think about what will work best.  But for now, we're just going to get out our caveman club and flail away... and then grunt happily when we get a solution!

 

 

Description: oggle.jpgThe Problem:

In this first small programming exercise, we will consider how we can solve Boggle. If you haven't played in awhile, here's the gist of the game: There are 16 cubes with letters on the faces. These cubes are randomly arranged in a 4x4 matrix by shaking the boggle game. The goal of the game is to make words out of these letters by traversing adjacent (horizontal, vertical or diagonal) tiles.  This "chain" of letters may snake all over the board, but you can only use each tile once, i.e., no fair using the same letter twice in a word. In a fixed amount of time players must make as many words as possible. Words are then scored as follows: 1 point for each 3-4 letter word, 2 points for a 5-letter word, 3 points for a 6-letter word, 5 points for a 7-letter word, 11 points for a 8 (or more)-letter word.

The Assignment: Overview

In this problem, you are asked to solve Boggle boards exhaustively in whatever way you can (go Fred Flintstone!): given a particular boggle board as input, your algorithm should enumerate all possible words that can be found in that Boggle board. 

The dictionary we will use for our game of Boggle is the Tournament Scrabble Wordlist which includes 178,691 words.  I've cleaned up and provided a file of dictionary words for you here.

Your program should be given a dictionary and an NxN boggle board (either in command line or program params, up to you).  It should then run and discover all possible words existing in the given board and print out a summary of its findings. 

Details:

This is not a particularly hard problem...provided you think it through! (Hint: elegance, recursion).  Just as a reference point:  my solution has one main function of about 15 lines, plus three smaller helpers to load/print out boards and stuff.  Without comments, the whole thing fits on a page.   

How to think about this problem:

The main point of this exercise is to just get everybody warmed back up on Python, but of course we also want to get our problem-solving knives honed up. Although we don't know much about it in any formal sense (but we will soon!), this problem involves exploration of a large space of possible states to find solutions...which is what a lot of AI is based on. In this case, a "state" is a place I've ended up after taking some path across the board, starting from some starting position...the letters in the path you've followed form a string...which might or might not be a "solution", i.e., depending on whether this string you have is in the dictionary. Ok, so it's really pretty simple: you have to write a program that (a) starts in each of the possible starting points on the boggle board; and (b) explores all possible paths from that point, recording/scoring any correct words it finds along the way. Put this way, it's simple: your key needs are a function that, given a current position, generates all possible adjacent positions (gotta stay on the board!). Then you have to consider that not all adjacent positions are possible: you have to subtract away any tiles that are already on the path you've already explored (can't use a tile twice!). Then you put it together: start at some position, see if the letter it contains is a legal word (if so, score it), then generate all possible next positions to jump to from there, jump to each one (adding its letter to the path)...and then repeat until none of your paths can go any further. If your brain is thinking "massive recursion!" then you're on the right track...

Programming Deliverables:

To make sure that everyone is moving in the right direction from the start, and to keep you on track, we'll break this project up until a couple of deliverables:

Part 1: For this part, you'll need to get a few of the basic pieces in place, before moving on to actually put them together into a solution. What I'll expect to see is:

Here is a shot of what these functions should look like in action. To help you get started, here is my useful little "GenBoard" Python program that randomly creates a new Boggle board file of specified size. Makes it easy to create new testing boards!

See below for exact deliverables for your submissionp packet for this part.

Part II: This is the final deliverable for this project. What I'll expect to see here is your fully functional program. Note that you might want to consider re-factoring your code from Part 1 a bit. In particular, you'll probably want to rebuilt the functionality from ExamineState into your broader function for exploring state after state throughout the whole board. And of course, you'll need a main function that loads everything up, reports starting board and resulting scores, and otherwise controls the action. What I'll expect to see here are:

See below for the detailed deliverables to put into your submission packet for this part.

Analysis questions: thinking about what your program is showing you about the problem 

As explained on our first day, this is NOT a "learning programming" class. This is the upper division, we can assume you all know very well how to program, so let's focus on the real meat. As real computer scientists, creating the code is incidental; what really interests us is using a program to explore the nature of a particular problem. Thus, the following write-up asks you to reflect on your experience in programming the solution, and use it to explore this problem more deeply. In keeping with our emphasis on thinking over programming, the write-up will be worth a substantial amount (up to 50%) of the total points, so be sure to leave time for it in your time planning! Your write-up should be professionally neat, with clearly labeled answers to each of the following:

  1. A clear description of your algorithm, i.e., the approach/strategy that your code takes in solving the problem.   Being able to clearly outline an algorithmic approach is a valuable communication skill in our business, and demonstrates the extent to which you truly understand what you're doing. Do NOT walk through your functions/code in low-level detail! You need to describe how your program solves the problem abstractly, as in the key features of the approach and the steps the program goes through in executing it.
  2. Answer to the following "thinking" questions. Professionally present your answers to each as clear narrative interspersed with graphs, figures, equations and whatever else you need.
    1. Observe your own results: Run your solver on several 4x4, 3x3, and 2x2 boards. How many different words did your solver explore on each? How much time was taken on each. Now analyze: Come up with a curve showing your results. Then use this to predict the time/moves it would take to explore a 5x5 board.
    2. Analyze the problem generally:  How many possible combinations of letters (i.e. actual words or not) can be constructed from an NxN board? Walk through your reasoning carefully, showing how your value comes together. Let's keep it simple just to get a decent upper bound without needing a PhD in combinatorics: Ignore detailed paths possible on the board and just assume that every letter on the board could be chained with every other letter on the board...how many words could be made that way? How does your analysis match up with your empirical findings in the last question?
    3. Use your solver to solve at least 10-20 different boards, then ponder the solution stats you got. Based clearly on your observations, consider the following:  Suppose there is a Boggle competition where human players are given a sequence of boards to solve, and the time they have to do so decreases with each board.  Now examine the outcomes from the boards that you've run your solver on. What strategy for finding words would a "smart" (or as we'll call it in this course, "rational") player employ to maximize points in a time-limited time? Don't just speculate, support your answer clearly with your empirical results!
    4. In the sample output provided above, there are two runs on the same board shown, with/without "cleverness" turned on...with drastic differences in time/resources used to find identical results.  What the heck could that devious Dr. D be doing here to achieve this? Magic? Hint: put in some print statements to watch your program work...and then reflect on the implications of where effort is wasted.  The difference between the two outputs in my source code is exactly one line of code...plus another easily-created resource.

To turn in:

A professional packet with the following items in exactly this order for each part:

Part 1 packet:

  1. Cover sheet:  Name, course, assignment title, date
  2. Printouts of your program running the dynamically assigned boards. THIS LINK to the testing boards will be activated shortly before the due time. Test boards will be no larger than 4x4.
  3. Your fully-commented  code (maybe be duplex printed). All code must be clearly readable, nothing cut off, no hard-to-read screenshots!

Part 2 packet:

  1. Cover sheet:  Name, course, assignment title, date
  2. Your analysis questions: questions presented in the order given, each question clearly labeled with the question text, then your answer to it. Nice and clean and readable.
  3. Printouts of your program running the dynamically assigned boards. THIS LINK to the testing boards will be activated shortly before the due time.
  4. Your fully-commented  code (maybe be duplex printed).

Important: Make sure all printouts in the packet are clear and 100% readable. If I can't read it, I can't score it!