Difference between revisions of "Tetris Assignment"

From CSE425S Wiki
Jump to navigation Jump to search
 
(18 intermediate revisions by the same user not shown)
Line 3: Line 3:
  
 
[https://www.coursera.org/learn/programming-languages-part-c/supplement/8lyk9/homework-6-instructions Coursera Instructions]
 
[https://www.coursera.org/learn/programming-languages-part-c/supplement/8lyk9/homework-6-instructions Coursera Instructions]
 
=Possible Setup Issue Fix=
 
 
Before you embark on the assignment be sure to test out running uw6runner.rb.  We have had two occurrences on Windows with Ruby 2.3 which fail producing the stack trace below:
 
 
<nowiki>C:/Ruby23-x64/lib/ruby/2.3.0/tk/itemconfig.rb:115:in `hash_kv': wrong argument type nil (expected Array) (TypeError)
 
        from C:/Ruby23-x64/lib/ruby/2.3.0/tk/itemconfig.rb:115:in `itemconfig_hash_kv'
 
        from C:/Ruby23-x64/lib/ruby/2.3.0/tk/canvas.rb:722:in `_parse_create_args'
 
        from C:/Ruby23-x64/lib/ruby/2.3.0/tk/canvas.rb:735:in `create'
 
        from C:/Ruby23-x64/lib/ruby/2.3.0/tk/canvas.rb:758:in `create_self'
 
        from C:/Ruby23-x64/lib/ruby/2.3.0/tk/canvas.rb:751:in `initialize'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6graphics.rb:91:in `new'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6graphics.rb:91:in `initialize'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:402:in `new'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:402:in `block in draw_piece'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:401:in `map'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:401:in `draw_piece'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:263:in `draw'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6assignment.rb:87:in `set_board'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6provided.rb:273:in `initialize'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6runner.rb:19:in `new'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6runner.rb:19:in `runMyTetris'
 
        from C:/Users/estrian/git/425-dev/src/main/ruby/uw6/uw6runner.rb:24:in `<main>'
 
 
Process finished with exit code 1</nowiki>
 
 
If you encounter this problem try inserting the code below at the top of uw6runner.rb:
 
 
<nowiki>require 'tk'
 
require 'tkextlib/tile'
 
module TkItemConfigOptkeys
 
  def itemconfig_hash_kv(id, keys, enc_mode = [], conf = [])
 
    hash_kv(__conv_item_keyonly_opts(id, keys), enc_mode, conf)
 
  end
 
end</nowiki>
 
 
[https://stackoverflow.com/a/43476737 stackoverflow]
 
  
 
=Overview=
 
=Overview=
Line 55: Line 18:
 
=Enhancements=
 
=Enhancements=
 
1. In your game, the player can press the ’u’ key to make the piece that is falling rotate 180 degrees.<br/>(Note it is normal for this to make some pieces appear to move slightly.)
 
1. In your game, the player can press the ’u’ key to make the piece that is falling rotate 180 degrees.<br/>(Note it is normal for this to make some pieces appear to move slightly.)
 +
 
2. In your game, instead of the pieces being randomly (and uniformly) chosen from the 7 classic pieces, the pieces are randomly (and uniformly) chosen from 10 pieces. They are the classic 7 and these 3:<br/>
 
2. In your game, instead of the pieces being randomly (and uniformly) chosen from the 7 classic pieces, the pieces are randomly (and uniformly) chosen from 10 pieces. They are the classic 7 and these 3:<br/>
  
 
<center>
 
<center>
{| class="wikitable"
+
{| class="wikitable" style="background-color:#ccccff;"
 
|-
 
|-
| [-1,0] || [0,0] || &nbsp;
+
| style="width:64px; height:64px; text-align:center;"| [-1,-1]
 +
| style="width:64px; height:64px; text-align:center;" | [0,-1]
 +
| style="width:64px; height:64px; text-align:center; background-color:#ffffff;" | &nbsp;
 
|-
 
|-
| [-1,1] || [0,1] || [1,1]
+
| style="width:64px; height:64px; text-align:center;"| [-1,0]
 +
| style="width:64px; height:64px; text-align:center;" | [0,0]
 +
| style="width:64px; height:64px; text-align:center;" | [1,0]
 
|}
 
|}
{| class="wikitable"
+
 
 +
&nbsp;
 +
 
 +
{| class="wikitable" style="background-color:#ccccff;"
 
|-
 
|-
| [-2, 0] || [-1, 0] || [0, 0] || [1, 0] || [2, 0]
+
|style="width:64px; height:64px; text-align:center;"| [-2, 0]
 +
|style="width:64px; height:64px; text-align:center;"| [-1, 0]
 +
|style="width:64px; height:64px; text-align:center;"| [0, 0]
 +
|style="width:64px; height:64px; text-align:center;"| [1, 0]
 +
|style="width:64px; height:64px; text-align:center;"| [2, 0]
 
|}
 
|}
{| class="wikitable"
+
 
 +
&nbsp;
 +
 
 +
{| class="wikitable" style="width:128px; height:128px; text-align:center; background-color:#ccccff;"
 
|-
 
|-
| [0, 0] || &nbsp;
+
|style="width:64px; height:64px; text-align:center;"| [-1, 0]
 +
|style="width:64px; height:64px; text-align:center; background-color:#ffffff;"| &nbsp;
 
|-
 
|-
| [0, 1] || [1, 0]
+
|style="width:64px; height:64px; text-align:center;"| [0, 0]  
 +
|style="width:64px; height:64px; text-align:center;"| [0, 1]
 
|}
 
|}
 
</center>
 
</center>
Line 83: Line 63:
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
| [0][0]
+
|style="width:64px; height:64px; text-align:center; background-color:#ccccff;"| [0, 0]
 
|}
 
|}
 
</center>
 
</center>
Line 91: Line 71:
 
=How To Run The Game=
 
=How To Run The Game=
 
We recommend you not use irb to load uw6runner.rb and start a game. We have not had success getting the graphics library to restart properly more than once inside irb, so you would likely have to exit the REPL after playing each game anyway. You can use the REPL for testing individual methods and exploring the program, but to launch a game, go outside irb and run ruby uw6runner.rb (or to make sure the original unenhanced game still works correctly, run ruby uw6runner.rb original). Make sure the 4 Ruby files are in the same directory and run the ruby command (or irb when exploring) from that directory.
 
We recommend you not use irb to load uw6runner.rb and start a game. We have not had success getting the graphics library to restart properly more than once inside irb, so you would likely have to exit the REPL after playing each game anyway. You can use the REPL for testing individual methods and exploring the program, but to launch a game, go outside irb and run ruby uw6runner.rb (or to make sure the original unenhanced game still works correctly, run ruby uw6runner.rb original). Make sure the 4 Ruby files are in the same directory and run the ruby command (or irb when exploring) from that directory.
 +
 +
{{RubyToRun|uw6runner|uw6|main}}
 +
 
=Requirements=
 
=Requirements=
 
For our testing scripts to work, you must follow these guidelines.
 
For our testing scripts to work, you must follow these guidelines.
Line 99: Line 82:
 
* You must have a MyPiece class and it must define a class constant All My Pieces that contains exactly the ten “normal” pieces (i.e., the initial seven plus the three additional pieces from enhancement two). It must not contain your cheat piece. It must be in the same format as the All Pieces array in the provided code.
 
* You must have a MyPiece class and it must define a class constant All My Pieces that contains exactly the ten “normal” pieces (i.e., the initial seven plus the three additional pieces from enhancement two). It must not contain your cheat piece. It must be in the same format as the All Pieces array in the provided code.
 
* All your new pieces, including your cheat piece, must use the same format as the provided pieces.<br/>Hint: Be particularly careful to have enough nesting in your arrays or your game may be subtly, almost imperceptibly, incorrect.
 
* All your new pieces, including your cheat piece, must use the same format as the provided pieces.<br/>Hint: Be particularly careful to have enough nesting in your arrays or your game may be subtly, almost imperceptibly, incorrect.
* Do not use the Tk library directly in any way. The only use of Tk should occur indirectly by using instances of classes defined in uw6graphics.rb as needed (only a little is needed). Do not have require ’tk’ in your uw6assignment.rb file (or any other use of require for that matter).
+
* '''Do not use the OpenGL library directly in any way.''' The only use of OpenGL should occur indirectly by using instances of classes defined in uw6render.rb as needed (only a little is needed). Do not have require ’opengl’ in your uw6assignment.rb file (or any other use of require for that matter).
  
 
=Advice and Guidance=
 
=Advice and Guidance=

Latest revision as of 02:25, 7 December 2024

Credit

All credit for this assignment goes to Prof. Grossman and his team at UW.

Coursera Instructions

Overview

This assignment is about a Tetris game written in Ruby. There are four Ruby files involved:

  1. The Ruby code in uw6provided.rb implements a simple but fully functioning Tetris game (see, for example, http://en.wikipedia.org/wiki/Tetris#Gameplay).
  2. In uw6assignment.rb, you will create a second game that is Tetris with some enhancements, described below. This is the only file you will submit (other than, as usual, a file you used for testing).
  3. The Ruby code in uw6runner.rb is the main starting point. From the command-line (not within irb), you can run ruby uw6runner.rb to play a Tetris game that includes your enhancements. To use the original game rather than your code in uw6assignment.rb, run ruby uw6runner.rb original.
  4. The Ruby code in uw6graphics.rb provides a simple graphics library, tailored to Tetris. It is used by the Tetris game in uw6provided.rb. Your code can also use the classes and methods in uw6graphics.rb (as well as the classes and methods in uw6provided.rb), except for the methods marked with comments as not to be called by student code. Your code cannot use the Tk graphics library directly.

You will turn in only uw6assignment.rb, so your solution cannot involve modifying any of the provided code. Instead, use subclassing (since, after all, this is the OOP portion of the course) to nonetheless reuse as much of the code as possible. Some code-copying will still be necessary, but you should try to minimize it. Your solution should also not change any of the provided classes in any way. You will define subclasses that behave differently. As a result, the provided Tetris game will run without change.

Much of the work in this assignment is understanding the provided code. There are parts you will need to understand very well and other parts you will not need to understand. Part of the challenge is figuring out which parts are which. This experience is fairly realistic.

Enhancements

1. In your game, the player can press the ’u’ key to make the piece that is falling rotate 180 degrees.
(Note it is normal for this to make some pieces appear to move slightly.)

2. In your game, instead of the pieces being randomly (and uniformly) chosen from the 7 classic pieces, the pieces are randomly (and uniformly) chosen from 10 pieces. They are the classic 7 and these 3:

[-1,-1] [0,-1]  
[-1,0] [0,0] [1,0]

 

[-2, 0] [-1, 0] [0, 0] [1, 0] [2, 0]

 

[-1, 0]  
[0, 0] [0, 1]

The initial rotation for each piece is also chosen randomly.

3. In your game, the player can press the ’c’ key to cheat: If the score is less than 100, nothing happens.
Else the player loses 100 points (cheating costs you) and the next piece that appears will be:

[0, 0]

The piece after is again chosen randomly from the 10 above (unless, of course, the player hits ’c’ while the “cheat piece” is falling and still has a large enough score). Hitting ’c’ multiple times while a single piece is falling should behave no differently than hitting it once.

How To Run The Game

We recommend you not use irb to load uw6runner.rb and start a game. We have not had success getting the graphics library to restart properly more than once inside irb, so you would likely have to exit the REPL after playing each game anyway. You can use the REPL for testing individual methods and exploring the program, but to launch a game, go outside irb and run ruby uw6runner.rb (or to make sure the original unenhanced game still works correctly, run ruby uw6runner.rb original). Make sure the 4 Ruby files are in the same directory and run the ruby command (or irb when exploring) from that directory.

file to run: src/main/ruby/uw6/uw6runner.rb Ruby logo.svg

Requirements

For our testing scripts to work, you must follow these guidelines.

  • Your game should have all the features of the original Tetris game, as well as the enhancements.
  • The subclasses you create must start with My followed by the name of the original class. For example, your Tetris class should be called MyTetris. We have provided empty class definitions for you to complete. You do not need any other classes.
  • Do not add to or modify any classes defined in other files or the standard library.
  • It is required that your board MyBoard has a next piece method that provides the same functionality that Board’s next piece provides, which is that it sets @current block to the next piece that will fall, which might or might not be the cheat piece.
  • You must have a MyPiece class and it must define a class constant All My Pieces that contains exactly the ten “normal” pieces (i.e., the initial seven plus the three additional pieces from enhancement two). It must not contain your cheat piece. It must be in the same format as the All Pieces array in the provided code.
  • All your new pieces, including your cheat piece, must use the same format as the provided pieces.
    Hint: Be particularly careful to have enough nesting in your arrays or your game may be subtly, almost imperceptibly, incorrect.
  • Do not use the OpenGL library directly in any way. The only use of OpenGL should occur indirectly by using instances of classes defined in uw6render.rb as needed (only a little is needed). Do not have require ’opengl’ in your uw6assignment.rb file (or any other use of require for that matter).

Advice and Guidance

For the piece you are adding that has 5 squares in it and is not a line, be sure to add the piece as pictured and not its mirror image.

  • It takes time to understand code you are given. Be patient and work methodically. You might try changing things to see what happens, but be sure you undo any changes you make to the provided code.
  • The sample solution is about 85 lines of code. As always, that is just a rough guideline; your solution might be longer or shorter.
  • While you should not copy code unless necessary, some copying will be necessary. After all, the original game may not have functionality broken down into overridable methods the way you would want and you are not allowed to change the provided code. This is a fairly realistic situation.

(Lack Of) Challenge Problem

The best thing to do to continue the assignment is to implement an additional enhancement (or more) to your game, but we do not have a reasonable way to grade this and additional enhancements could possibly mess up auto-grading. So:

  • This assignment will not have a graded challenge problem.
  • Be sure to turn in a solution that adds only the three asked-for enhancements.
  • Then enjoy trying additional enhancements. Be creative.

We encourage you to share on the discussion forum what you did but not how you did it as that would take away the fun from others who might try to repeat your accomplishment.