{"id":25219983,"url":"https://github.com/ggleblanc2/sos","last_synced_at":"2026-05-01T13:31:55.585Z","repository":{"id":75064665,"uuid":"478132249","full_name":"ggleblanc2/sos","owner":"ggleblanc2","description":"This repository holds the code to create a Java Swing SOS game.","archived":false,"fork":false,"pushed_at":"2022-04-05T14:15:58.000Z","size":74,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T11:17:46.173Z","etag":null,"topics":["java-8","sos","swing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ggleblanc2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-05T13:05:24.000Z","updated_at":"2022-04-25T00:50:16.000Z","dependencies_parsed_at":"2023-02-27T00:00:50.495Z","dependency_job_id":null,"html_url":"https://github.com/ggleblanc2/sos","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ggleblanc2/sos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggleblanc2%2Fsos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggleblanc2%2Fsos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggleblanc2%2Fsos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggleblanc2%2Fsos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ggleblanc2","download_url":"https://codeload.github.com/ggleblanc2/sos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggleblanc2%2Fsos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32499681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java-8","sos","swing"],"created_at":"2025-02-10T21:49:46.388Z","updated_at":"2026-05-01T13:31:55.568Z","avatar_url":"https://github.com/ggleblanc2.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SOS\n\n## Introduction\n\n[SOS](https://en.wikipedia.org/wiki/SOS_(game)) is a game for two or more players.  Before play begins, a square grid of at least 3x3 squares in size is drawn.  Players take turns to add either an \"S\" or an \"O\" to any square, with no requirement to use the same letter each turn. The object of the game is for each player to attempt to create the straight sequence S-O-S among connected squares (either diagonally, horizontally, or vertically), and to create as many such sequences as they can. If a player succeeds in creating an SOS, that player immediately takes another turn, and continues to do so until no SOS can be created on their turn. Otherwise turns alternate between players after each move.\n\nMy Java Swing version of SOS was designed for two players.  The grid can be any size between 3x3 and 10x10.  Here's what the GUI looks like when the game starts.\n\n![Initial GUI](readme-resources/sos1.png)\n\nThe GUI is a tiny 542x397 pixels.  It should fit on any modern monitor screen.\n\nHere's the GUI when using the full 10x10 grid.\n\n![Initial GUI](readme-resources/sos2.png)\n\nTo place an S or an O, the player left-clicks on the square.  The following dialog asks the player if he wants to mark an S or an O.\n\n![S or O](readme-resources/sos4.png)\n\nHere's the GUI after player 1 gets an SOS.\n\n![SOS](readme-resources/sos3.png)\n\nAfter the grid is filled, the following dialog asks if the players want to play another game.\n\n![Another Game](readme-resources/sos5.png)\n\n## Explanation\n\nOracle has a helpful tutorial, [Creating a GUI With Swing](https://docs.oracle.com/javase/tutorial/uiswing/index.html).  Skip the Learning Swing with the NetBeans IDE section.\n\nI coded this Swing application in tiny, testable pieces.  More often than not, I'd make a syntax or logic error in the 10 lines or so I just added to the code.  Because I test after writing 10 lines of code, the error is probably in those 10 lines, and I can find the mistake fairly easily.\n\nWhen I create a Swing GUI, I use the [model-view-controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (MVC) pattern.  This pattern helps me to separate my concerns and focus on one small part of the Swing application at a time.\n\nThe MVC name implies that you create the model first, then the view, and finally the controller.  This is an iterative process.  My first ideas for the application model turned out to not work in practice, so I made changes to the model.\n\nA Swing model consists of one or more plain Java getter/setter classes.\n\nA Swing view consists of one `JFrame` and one or more `JPanels`.\n\nA Swing controller consists of one or more actions and/or listeners.\n\nA Swing application implements the MVC pattern in the following manner:\n\n- The view reads information from the model.\n- The view does not update the model.\n- The controller updates the model and revalidates/repaints the view.\n\nThe controller is usually not one single class.  In Swing, each action or listener modifies its part of the model and its part of the view.\n\n### Model\n\nI wrote three model classes for this Swing application.\n\nThe `SOSModel` class is a plain Java getter/setter class that holds a logical model of the game grid (`char[][]`), two `int` scores, the `int` width of the grid in cells, from 3 to 10, the `int` player turn indicator, and a `java.util.List` of line segments.\n\nThe `LineSegment` class is a plain Java getter/setter class that holds a line `Color`, a start coordinate, and an end coordinate.\n\nThe `Coordinate` class is a plain Java getter/setter class that holds an `int` row number and an `int` column number.\n\n### View\n\nThe view consists of a `JFrame`, a control `JPanel`, a drawing `JPanel`, and two `JOptionPanes`.\n\nAll Swing applications must start with a call to the `SwingUtilities` `invokeLater` method.  This method ensures that all Swing components are created and executed on the [Event Dispatch Thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html). \n\nThe `JFrame` has a default `BorderLayout`.  I placed the drawing `JPanel` in the center and the control `JPanel` in the east.\n\nThe drawing `JPanel` draws the grid, the S and O moves, and the lines.\n\nThe control `JPanel` uses subordinate `JPanels` to create the score area and the grid width area.\n\n### Controller\n\nThe controller consists of a `MouseListener` and a lambda expression.\n\nThe `GameboardListener` class extends a `MouseAdapter` and implements the logic to place an S or O in the appropriate grid square, checks to see if an SOS is created, and determines whether or not the game is over (the grid is filled).\n\nThe lambda expression gets the grid width in cells from the `JSpinner` and updates the model and the view.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggleblanc2%2Fsos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fggleblanc2%2Fsos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggleblanc2%2Fsos/lists"}