Recent Work, 7/3/2016

The most recent version of Logic Lights can be found here.  Links to a tutorial video and source code are also there.

Screen Refactor:

  • Pushed level selection into Screen() class, with some additional work in the player and game class to streamline things.  
    • Integration is bad at the handle_events() level.  Rather than a nice, clean encapsulation, the level selection code from selector() was duplicated in full. 
    • Fixed a random error in logout by moving order of event handling around.  Not a good solution, but error may never recur.  If I try to clean the level selection up I may have to remember what I did, though.
  • Selector page is now fully integrated in the way win, retire, and login are.  Only need to do the same thing for the game() function

Monthly Overview for June

General:

  • Changed the look and feel of the buttons so that they look more button-y to the user.
  • Ditto for factories, which now have a slightly different look than the elements you take out of them.
  • Fixed a save error that didn't appear in my testing environment.  
  • Changed the win screen so that any click doesn't switch it off.  This means you won't accidentally click out and not get to see the confetti.

Graphics Refactor:

The purpose of the graphics refactor is to allow rescaling so that players can build larger logic diagrams.  This will involve creating scalable classes that use Game() or Viewer() information to rerender base objects upon a rescale.

  • Actions:
    • Worked on the ColorScheme() class.

Screen Refactor:

The purpose of the screen refactor is to move all game logic into the Game() and Screen() classes rather than in a series of functions that swap the game state between them.

Current Plan for Screen Refactor

  1. Push all actions on the Win and Retire screens into Game() and Screen() objects. 
  2. Push all actions in the Login screen into Game() and Screen() objects.
  3. Work on the selection screen to get levels and tutorials into Game() and Screen objects.
  4. Push all actions in the Selection screen into Game() and Screen() objects.
  5. Work on moving the program into the Game() object so that it's manipulable.
  6. Integrate parts of that into the Win and Retire screen.. (i.e., you can move stuff around, but not alter the program).
  7. Work on moving inputs in the game() function into Game() and Screen() objects.
  8. Push Game screen into the Game() and Screen() objects.
  9. Integrate the Win and Retire screens.
  • Work completed in June:
    • Screen integration has begun.
    • All screens now use internal game states in the screen loop, allowing for the integration.
    • Win, Retire, and Login screens are still handled by functions, but have a standard organization that ignores the specific content of the screen.  There are some minor differences in the code, but that is because certain actions aren't used in those screens.
    • An event handling method has been implemented in the Screen() class that cycles through buttons and action objects active for that screen.  All button evaluations are now in those screens.
    • Created a specialized container for the confetti on the win screen, allowing me to put the confetti into the game Screen() object.
    • All clock operations are now integrated into the Game() object.
    • Created three levels in the screens: background, middle (action) ground, and foreground.
    • Screen set-up has its own function, pulled out of main().  Abstracting out the logic from the control functions added more and more logic to main() that wasn't in the control loop but will need to be done when main() is removed. 
    • Created a Message() class that outputs text with a variable in a simple way.  Also created a FadeIn() class that takes a message and fades it in from BLACK to whatever color (WHITE or YELLOW).
  • Created some simple Action classes that are held by the screens.  The actions are fairly simple: they couple one event or type of event with a method from a single object, either a game or a screen so far.  The action classes are attached to the relevant game screens, and when a screen is active, each event is passed through every listener to see if their action should be activated.  They are broadly keyboard listeners or mouse listeners, and several have been made so far.
    • Integrated close button decoration into a Quit() action.
    • Created a KeyInput() listener that modifies a string variable from input.  Only uses caps and only uses
    • Created a SingleKey() listener that couples a key to an action.  Right now it only controls the enter button, but it can be used for keyboard shortcuts later. 
    • Made an AnyKey() listener to allow the screen to advance on any keyboard input. "Press any key to continue."
  • Patches:
    • Game logic in the main() function is now screen based.  This entire function disappears when the screen integration is completed, but this means
    • Game screens only take the game object as an argument, taking all their information from it.
  • To Do:
    • Allow moving the game pieces around after the win (but no adding/removing elements) (May)

Other Ideas:

  • Button Action: Activate buttons on MOUSEBUTTONUP if the mouse is still over the same button as it was when the game received a MOUSEBUTTONDOWN command.
  • Help Screen (April): Create an in-game help screen.
  • Tip Jar (April): I know you want to help support the game.
  • Level Randomization (April): Randomize level label so that player cannot know what the puzzle is before he clicks on it.
  • Level Unlock (April): Only allow players to work on levels with more switches if a certain percentage of previous puzzles are completed (perhaps all).
  • Unlimited Level Size (April): After graphic refactor, allow players to play levels of arbitrary size.  Game logic already allows this, but there may be a few specifics with the graphics and so on that need to be taken care of before this actually works. 
  • Logic Table: Show level's logic table to player.
  • Save Play State (April): Save the game during play.
  • Win Quality (April): Give more stars for wins with fewer elements in the program or for harder puzzles (see Difficulty Levels, above)

Program Elements:

  • Probe Light: Allow players to insert a probe at various points so that they can see what the output of a sequence of logic is.
  • Ground (May): Integrate a ground so that solutions are only viable when all buttons are connected to something.  Current change in thinking is to include only one ground, vertical at the bottom of the play area, so that player can only ground buttons.
  • Difficulty Levels (April):  Need to include difficulty levels by changing the available gates.  Hard level: NOR-only.


Other Things to Do for Graphics:

  • Different pointers for different purposes:
    • Mostly use the arrow, but
    • Add a pointy finger over the buttons, and
    • Add a grabby hand for movable objects and factories, that
    • Becomes a closed hand when pulling something around, while
    • Showing a soldering iron over pads and while drawing wires, while
    • becomes a clasp when the end of a wire is over a terminal. 
  • Border for play area.
  • Draw convincing trash can. (April)
  • Change "1 Switch", "2 Switches" labels to some kind of graphical depiction. (April)

Other Versions:

I am not satisfied with having only a Windows version of this software.  I would like to expand to other operating systems or delivery methods.  In order, the priorities are:

  • Web Version (includes: learn JavaScript)
  • Android Version (includes: learn Java, etc.)
  • Mac Version (need a Mac to use Py2App)

Recent Work, 6/30/2016

In the screen refactor:

  • All loop functions for Win and Retire screens have been integrated into Game() and Screen() objects.  Just need to automate their initialization.
  • Started moving event handling into the the Screen() class, with classes for different kinds of events.  Current goal is to get the simplest screens (Win and Retire, which should merge eventually) to be handled completely in the game object.
    • An action that occurs when any key is pressed is in the AnyKey() class.
    • An action that occurs when the quit button [X] is in the Quit() class.
    • Moved button activation into screen refactor.

Errors Seen but Not Heard:

  • Apparent problem with saving.  Occasional loss of file permissions.  Possibly due to programming in cloud.

Current Plan for Screen Refactor

  1. Push all actions on the Win and Retire screens into Game() and Screen() objects. 
  2. Push all actions in the Login screen into Game() and Screen() objects.
    • Need to get some interactivity with the name variable.
  3. Work on the selection screen to get levels and tutorials into Game() and Screen objects.
  4. Push all actions in the Selection screen into Game() and Screen() objects.
  5. Work on moving the program into the Game() object so that it's manipulable.
  6. Integrate parts of that into the Win and Retire screen.. (i.e., you can move stuff around, but not alter the program).
  7. Work on moving inputs in the game() function into Game() and Screen() objects.
  8. Push Game screen into the Game() and Screen() objects.
  9. Integrate the Win and Retire screens.

Recent Work, 6/19/2016

Screen Refactor:

  • Moved confetti from Game() to a specialized container.  Will see if I can modify the FadeIn() class so that they both inherit from the same Animation() class.
    • The wingding container is now a part of the middle-ground animations for the win-screen (animations can be in back-, middle-, or fore- grounds).
  • Coupled sequence logic to game state in main() to help with the refactor.
  • Turned the "Press any key to continue" message on the win and retire screens into buttons.  Now pressing a key or clicking on the message changes state.

Recent Work, 6/18/2016

You can download most recent release is here.  This includes links to the source code and a YouTube demo.

Modifications:

  • Modified screen draw functions so they don't take any arguments: the Screen objects subscribe to the game object now for other other reasons, so I don't have to send them the display.
  • Retire screen is now as encapsulated as the win screen.
  • Found the save error.  For some reason it stopped saving names in lower case.  Fixed it.

Drudge work:

  • Added comments to Game() class.

Recent Work, 6/14/2016

Refactor progress:

  • Moved both kinds of animation for the win screen into the Screen object from the main screen.  Some code is too game-specific still, requiring a container class for the animated confetti.
    • This required putting the clock into the Game() class.
    • Both the middle-ground flying wingdings and the foreground fade in.
    • Minor upgrades to win screen 
  • Changed the win screen to keyboard exit only and added a message to that effect.

To Do:

  • Make a container for the confetti.

Recent Work, 6/12/2016

You can get the current version of Logic Lights here.  It does have a rather glaring new issue, but it doesn't affect the game play, it just doesn't remember anything you did after you log out.

Corrections:

  • Fixed the ghost text.  This was an effect of the hack-in during the refactor.  Since I want everything to work every step of the way (or as much as possible), I have some strange code that will disappear later.  In this case, I kept adding more labels to the Screen object for the login screen, but this probably would have disappeared after screens are self-executing.
  • The game window is not resizable, but page where levels were chosen still included resize code.  So I deleted it. 

Modifications:

  • Modified the Message class so that a variable is a method subscription such as thing.get_name or game.get_score that is updated during rendering.
  • Have moved to creating the display in the Game() object (currently central; this will change when the game() function is obsolete).  For now, this means that each of the screen functions takes only one argument (central), but it also allows me to make each function look more like its final state when fully incorporated into the Game() object.
  • Moved the exit controls to the Game() class.

To Do:

  • Will need to add active elements in foreground for win screen.  Remember: the win notice fades in.
  • Also need to add active animations for the confetti.  (probably in Game() class, not Screen()).

Recent Work, 6/11/2016

Additions:

  • Refactored on-screen buttons (logout, retire, etc.)
  • Been modifying the Screen() class.  Have moved all graphics for the login screen into a Screen() object and have pushed the retire button into another one.  Graphics refactor looking good.  Should be able to finish it without finishing the full game refactor.

 

Errors:

  • Found a persistent error (in the version 0.3 releases) where the game isn't loading the old data for players.  Did not show up until I accidentally deleted my old saves -- don't know why.  It was working in all three before I did the 0.3c release.
  • One shadow persists in login screen.  Not sure where it's from.  Does not appear in the initial load.

Recent Work, 6/5/2016

Entropy!

Found a problem (that's in the latest release) where the evaluation chain for the current state doesn't work correctly.  On top of that, a random error made me roll back because the game was retiring on its own.

After revising back to the old game and doing a little work, it fixed itself readily but unexpectedly.

Refactor:

  • Worked on Screen() and ColorScheme() classes, starting in on integration first with the pads.
    • Renderer needs to have top-level access to the game object.  Icky mixing between refactors seems to be needed.

Other Things to Do for Graphics:

  • Buttons and Factories need to be raised (or lowered?) to make their purpose clear.
  • Different pointers for different purposes:
    • Mostly use the arrow, but
    • Add a pointy finger over the buttons, and
    • Add a grabby hand for movable objects and factories, that
    • Becomes a closed hand when pulling something around, while
    • Showing a soldering iron over pads and while drawing wires, while
    • becomes a clasp when the end of a wire is over a terminal. 
  • Border for play area.

Monthly Overview for May

What I accomplished in working on Logic Lights in May, and current plans:

Completed:

Probes:

Created clasps that connect inputs directly to wires.  This means that a signal from a particular output can be accessed anywhere along an outgoing wire instead of just at its output terminal.

Wires:

Made the wires more variable in nature by creating a differing number of segment. Things that the wire segments can do that weren’t possible before include:

The segments can be moved around to make it easier to determine where the wire is.

The player can make new segments by pulling on the first and last wire segment, allowing for more complicated shapes.

To Do:

Carried Over:

From Feedback:

Add an in-game help screen describing the rules of the game (April)

Add a tip jar or donation button (April)

Levels:

Allow arbitrarily large puzzles with unlocks for larger puzzles based on earlier puzzles. (April)

Randomization of level labels for each user so that truth table isn't predictable from level number. (April)

Save game state when players close the game in the middle of play. (April)

Graphics:

Draw a convincing trash can. (April)

Remove the "1 switch" string on the level switch, replace with graphical representation (April)

Make the ground switch direction when connected to an input. (April)

 

Changing the winning condition:

Quality factors for wins: (April)

Status: I only have the two states, tried and won.  Having each of the three stars mean something different is a possibility.  One star for winning, one star for winning with the fewest possible number of elements, and one star for not making any extraneous materials (not throwing things away) is probably the best strategy.  This would, however, require me to figure out how to algorithmically solve the puzzle and reduce its size to a minimum.

Different Logic Elements:

Status: I only have the three logic elements.  It would be fun to do the whole game with just Nor-gates.

Puzzles complete only if all terminals wired. (April)

Status:  I have created the ground, but have not integrated it into the game or the win-check system.  I am still waffling on whether this is a good idea.

New:

From Feedback:

Allow moving the pieces around after a win.

In Notes:

Other Versions:

I am not satisfied with having only a Windows version of this software.  I would like to expand to other operating systems or delivery methods.  In order, the priorities are:

Web Version (includes: learn JavaScript)

Android Version (includes: learn Java, etc.)

Mac Version (need a Mac to use Py2App)

The last is probably the simplest, though.  Someone may even be willing to do it for me.

Refactors:

The following systems need to be reworked completely in order for the game to progress.

Game Screens:

I would like the game screens to be handled through a Game Screen class.  This will allow me to reuse more code.

Graphics and Graphics Options:

I would like to refactor the vector graphics from functions to objects (I may only need one shell class from which to refer to the functions).  This way I can more easily:

1. Change color the color scheme

2. Add symbols to the logic elements

3. Scale the size when I expand the number of puzzles.

 

Recent Work, 5/30/2016

The first release with the movable wires is up here.  For the first time, I'm including the source in the distribution.  I've also started marking the releases' code on GitHub because I just found out about that.

Errors Found and Fixed:

  • Clasps could form a circuit, causing crash  from infinite regression. Had to stop that.
  • Probably something else that I did just after I made the executable.

Recent Work, 5/28/2016

Getting pretty close to a new version, but the currently working one is here.

Since there's so much different now as compared to the original release, I'll probably do another video at the same time.

Additions:

  • Allows player to add segments to a wire's end and therefore make wires of arbitrary shape.

Fixes:

  • Finally found the error that wasn't updating the wires connected to a clasp.  Now, I probably have a lot of trimming to do, both with traces and with extraneous code.
  • Also fixed the disappearing wire problem (it was turning vertical wires into horizontal wires whenever the two endpoints were the same).  The fix will help to attach wires at different angles and to allow the player to add wire segments to make things more readable.
  • Fixed several errors with choosing clasps with two lines of code.
  • Fixed a minor error where the wire would flash out to a strange place when first created from a terminal (for one frame, most likely) before working correctly.
  • Another minor fix or fix along the way in the last day or two that I should have written down.

Errors:

  • Removing clasps sometimes works correctly, sometimes deletes clasp while selecting wire segment instead.
  • Wires connected by clasps are no longer being deleted when logic elements are tossed into the garbage.

 

Recent Work, 5/21/2016

The most recent release is always here.  Try it and have fun.

Modifications:

  • Cleared up a problem where the wire wouldn't connect to the center of a terminal.  Still other similar problems.  
  • Fixed an error in reconnecting old wires.  They didn't return to their original terminals if dropped.  Now they usually will.  Keeping an eye out in testing to see if the problem returns.

Recent Work, 5/19/2016

If you'd like to try the latest working game, it's here.  There's only a Windows version available right now, but there's also a link to the current source code (with, possibly, some horribly exposed bugs) if you want to run it on your machine.

Segment Fixes:

  • Got the segments redrawing correctly when moving logic elements around.  Minor work required on Segment() class, a little more in LogicWire().
  • Dropping the element on the pad just needed a reordering of the connection algorithm in the game loop.

Current Errors:

  • Vertical wire segments disappear randomly  (and have never reappeared and their container wires do not respond when I click on the place they should be) when:
    • a logic element is moved up and down.
    • a logic element is dropped atop a terminal.
  • Clasps go to strange places.  They will react now, but they don't go to the correct location, and sometimes get stuck on an input terminal.  They don't necessarily appear in the correct spot.  Most likely culprits:
    • LogicClap's set_position() method.
    • Segement's get_location() or get_distance() methods.
    • LogicWire's add_clasp(), get_relative_position(), or reset_pads() methods.

Reminders for Refactors:

  1. Graphics Refactor
    • Do all drawing through a wrapper class that will contain the vector graphics function as well as subscribing to the Theme.
    • This will allow changes in style based on user preferences:
      • The user will be able to change the color scheme of the game.
      • The user will be able to change the output style from IEEE symbols to European-style symbols, etc.
    • This will also help when implementing scaling for working on larger problems (5 or more gates).
  2. Screen Refactor
    • Need to encapsulate screens into Screen objects (the whole point of the LogicScreen package) to reduce duplication.
    • Should do similar work with the controller.

Recent Work, 5/18/2016

The current version of Logic Lights can be found here.

Modifications:

  • Got rudimentary wire segments working.  a wire is now drawn as three segments, kept internally.  Any "middle" segment moves (although this is usually three, for now).  
    • Creating and storing the segments in the wire both work.
    • Selecting a segment works.
    • Moving the segment works.
    • Both the LogicWire() and Segment() classes required work to get to this point.

Problems with Wires:

  • Moving the input or output does not change the input or output segment.
  • Dropping a new LogicElement directly on a terminal does not properly create the wire segments.
  • Clasps don't respond to changes in the wire, and so can be made to float in space.

Other Desiderata with Wires:

  • Want to use is_horizontal() method to draw wires connected to their clasps perpendicularly to the wire they're probing.
  • Want to be able to create additional segments but pulling on the wire ends.
  • Want to automatically make wires go around logic elements when placed.

Despite the problems in the display faced by segments, they have no functional value in the program -- the puzzles are unaffected.

Recent Work, 5/14/2016

You can find the current version of the game here.

Additions:

  • Worked mainly on clasps and getting the game into a state that would allow for the next release, which it's pretty close to right now.
    • Hardest error was that when you deleted a wire that had several probes clasped to it, only every other one was deleted (it took awhile to figure that out, in itself, rather than just the additional probes were not deleted).
    • Can now select clasped probes and move them around.  If the wire isn't connected properly at the end of a move, the clasp will return and the wire will be reattached to it.
    • Strange error came when the other side of a wire connected to a clas was deleted -- the whole program crashed.
  • Also, did a final render on a win, so that the last terminal wired is drawn as connected

Downgraded Items:

  • After playing around with multiple clasps, don't see a need to attach multiple wires to a single probe.  Works good enough without that.

To Do:

  • I need to get the wires to come in perpendicularly to each other at the clasps.  Right now that would be difficult and hacky (and the game is hacky enough), so this will need to wait until the wires have been refactored into segments.

Recent Work 5/11/2106

The current version of Logic Lights is kept here.

Additions in the last couple of days:

  • Background work on refactoring the wires to be composed of individual segments.
    • Some other things on hold during this refactor.
  • Created a working clasp to look in on wires.
    • Clasps are held in the wires they peek into.
    • Clasps can act only as inputs.
    • Had to modify wires to figure out relative position on the wire from absolute position and vice-versa.

To Do:

  • Clasps:
    • Need to be able to select wires attached to clasps, deleting the clasp if that wire was the last one attached to the clasp.
    • Similarly, need to be able to recognize clasp has been selected when a wire is being dragged around and add additional wires to the junction.
    • When wire with a clasp on it is deleted, the clasp is deleted, but not the wire that uses it as a probe.

Other things noticed:

  • When a logic element is placed in an invalid position where it would automatically connect to another element, the wire is created and even though the logic element isn't saved.

Recent Work 5/8/2016

You can get the current version of the game here.

Integrated:

  • Made black space on sides of wires to help clarify paths.

Worked on:

  • Making the wires more flexible through moving the kink around and adding more kinks.
    • Created some relative positioning for the the kink.
    • Made structure inside LogicWire() to handle multiple kinks.
  • Creating a probe or clasp to see what is going on inside of a wire without having to wire to an output terminal.
    • Created the base class, inherited from the Pad() class.
    • Created some logic inside of the LogicWire() class to work with the clasp, including deleting the clasp when the wire is deleted.

To Do:

  • Wires:
    • Need to create an indefinite set if independent wire segments that function as a single unit.
    • Need to be able to select wire segments and move them around, including creating new segments when a new one is required.
  • Clasp:
    • Need to flesh out the clasp and add logic to the event handlers to create a new clasp when placed on a wire.

Recent Work 5/4/2016

Modifications:

  • Continued internal modifications for refactor by moving game properties into a Game() object and moving some screen properties into the screen objects.  Progressing by modification, keeping a working program at all times,  This will probably require some clean up when I'm done.

Investigation:

  • Found an error I was looking for.  It happens when multiple wires are connected to a terminal and the wired terminal of another element overlaps it (both conditions must apply).  Now I have to move some of the code around to correctly prioritize selection in that case.