For this project, I specifically looked at 3 versus 3 basketball to test a graph for player movement and different passing and cutting sequences and see which strategies work the best to beat the defense and get to coring zones called Red Zones.
To turn this idea into an actual simulation, I made functions to create a court by dividing the half-court into a grid of 90 specific points. By compiling the court as a network graph, the simulation can compute and store paths easily with vertex integers. I also, mapped out the Red Zones, which mark where tall players, short players, and shooters score, the zones are made specifically for the different player profiles. Attackers dribble step-by-step between adjacent vertex’s and find the shortest path’s between initial and target vertexes to run plays like a “Give and Go” or a “V cut” with the goal of getting to these zones.
While I wrote helper functions to evaluate the grid partitions, construct the graph using proximity analysis, and handle the player and ball data structures. However, the working simulation was not fully achieved within the time given. For the unmade extensions of the project, I expect to continue this project and bring everything together so that: Offensive plays are run in a loop, letting the handler dribble toward their scoring zone while off ball attackers follow their paths. Defenders move one step closer along connected grid edges using a man to man strategy, dynamically sorting neighbors by graph vertex adjacency to actively follow their assigned attacker. Condition checks process on every single move, stopping the simulation to trigger a Turnover if a defender intercepts the ball, or calling a Score the exact second a player gets the ball in their designated Red Zone.
Overall, this project provides the exact court, movement graph, logic, and strategies needed to finalize fully functional 3vs3 basketball strategy simulation.
To turn this idea into an actual simulation, I made functions to create a court by dividing the half-court into a grid of 90 specific points. By compiling the court as a network graph, the simulation can compute and store paths easily with vertex integers. I also, mapped out the Red Zones, which mark where tall players, short players, and shooters score, the zones are made specifically for the different player profiles. Attackers dribble step-by-step between adjacent vertex’s and find the shortest path’s between initial and target vertexes to run plays like a “Give and Go” or a “V cut” with the goal of getting to these zones.
While I wrote helper functions to evaluate the grid partitions, construct the graph using proximity analysis, and handle the player and ball data structures. However, the working simulation was not fully achieved within the time given. For the unmade extensions of the project, I expect to continue this project and bring everything together so that: Offensive plays are run in a loop, letting the handler dribble toward their scoring zone while off ball attackers follow their paths. Defenders move one step closer along connected grid edges using a man to man strategy, dynamically sorting neighbors by graph vertex adjacency to actively follow their assigned attacker. Condition checks process on every single move, stopping the simulation to trigger a Turnover if a defender intercepts the ball, or calling a Score the exact second a player gets the ball in their designated Red Zone.
Overall, this project provides the exact court, movement graph, logic, and strategies needed to finalize fully functional 3vs3 basketball strategy simulation.
Introduction
Introduction
The Game
The Game
Basketball is one of the most played sports, however, many don’t realize it is heavily based off on strategies. Players pass and cut to the basket and pop out to the 3 point line all to create space for themselves or the ball handler. However, these movements have to be done in the right order so can maximize the numbers of ways to score. To achieve this optimization, I must understand what I are working with exactly. For this project, I will specifically be looking at 3 versus 3 basketball. In this style of basketball, the fastest way to score is to pass and then move to open spots where you can score from. I shall repeat this process until a player gets the ball in their “red zone” which is the area were they score from. For the simulation, I will assume that every time a player gets the ball in their red zone without any defenders guarding, they will shoot the ball and score.
The Court
The Court
To turn this idea into an actual simulation I made functions to create a functional court. Firstly, I divided the half-court into a grid of 90 points. I also mapped out the “red zones” for three different player profiles: tall players, short players, and shooters. Then, I use these points as vertices in an undirected graph, allowing the simulation to compute and store paths. This data structure also allow us to programmatically replicate basketball rules. Attackers need to dribble step by step between adjacent points, execute strategies to target position such as “Give and Go” and “V cut”. Overall, this setup allows us to generate sequences of strategies to make a player to score (namely, visiting a vertex that belongs to a Red Zone that corresponds to their profile) or to restart the game due to a turnover.
Basketball Court Visualization
Basketball Court Visualization
Base Court Visuals
Base Court Visuals
To make the court have the accurate measures of a basketball court, I looked at a 2D model of the lengths of court partitions. Also, I will keep the ratios of the court accurate and the visuals too. Since the width to length ratio of a half-court basketball court is 50:47 I will assume that it is a square and I will make it 1:1 so I can work with fractions that make the later partitions easier to understand. I will define all of our points respecting the distances of a basketball court:
◼
The corner 3 pointer is 1/12 of the basketball court’s width
◼
The top of the 3 point arch is exactly at the midpoint of the court’s width and is 2/3 high
◼
The paint is 2/3 high and 1/2 high, counting the summit
Additionally, I will make the 3 point arc and the paint’s summit curved to make the graphics and ratios even more realistic.
These ratios will be the base to our partitions and our grid of points.
These ratios will be the base to our partitions and our grid of points.
Makes the visuals of the basketball court with Graphics and I make the 3 point arc with the Resource Function , which creates an arc out of 3 points.
ThreePointArc
In[]:=
arcpts={{1/12,1/3},{1/2,2/3},{11/12,1/3}};arc=ResourceFunction["ThreePointArc"][arcpts];
In[]:=
innerarcpts={{1/3,1/3},{1/2,1/2},{2/3,1/3}};innerarc=ResourceFunction["ThreePointArc"][innerarcpts];
Generates the 3 pointer arc for any given court length and height:
In[]:=
generateArc[courtLength_Integer,courtHeight_Integer]:=CircularArcThrough[{{courtLength*1/12,courtHeight*1/3},{courtLength*1/2,courtHeight*2/3},{courtLength*11/12,courtHeight*1/3}}]
Generates the paints summit arc for any given court length and height:
In[]:=
generateInnerArc[courtLength_Integer,courtHeight_Integer]:=CircularArcThrough[{{courtLength*1/3,courtHeight*1/3},{courtLength*1/2,courtHeight*1/2},{courtLength*2/3,courtHeight*1/3}}]
Defines the points I am using to make the horizontal and vertical lines on the base court. These would be our point coordinates for a 1 by 1 court:
backround=Rectangle[{0,0},{1,1}];
verticalLines=Line {{1/12,0},{1/12,1/3}}, {{1/3,0},{1/3,1/3}}, {{2/3,0},{2/3,1/3}}, {{11/12,0},{11/12,1/3}};
horizontalLine=Line {1/3,1/3},{2/3,1/3};
Generates the vertical lines for the base court for any given court length and height:
In[]:=
generateVertCourtLines[courtLength_Integer,courtHeight_Integer]:=Line {{courtLength*1/12,0},{courtLength*1/12,courtHeight*1/3}}, {{courtLength*1/3,0},{courtLength*1/3,courtHeight*1/3}}, {{courtLength*2/3,0},{courtLength*2/3,courtHeight*1/3}}, {{courtLength*11/12,0},{courtLength*11/12,courtHeight*1/3}}
Generates the horizontal lines for the base court for any given court length and height:
In[]:=
generateHorizCourtLines[courtLength_Integer,courtHeight_Integer]:=Line {courtLength*1/3,courtHeight*1/3},{courtLength*2/3,courtHeight*1/3}
Compiles all of these lines and arcs to our basic court:
In[]:=
court= FaceForm[],EdgeForm[{Black,Thick}],backround, verticalLines, innerarc, arc, horizontalLine;
Generate Red Zones
Generate Red Zones
To make the court and eventually the simulation more realistic, I created “red zones” which are tailored to player profiles. Such as, tall players, short players and shooters.
First of all, the low, inside of the perimeter is where tall players will score, this area has the measures of 5/6 by 1/3 respective to the a 1 by 1 base square.
This will be the biggest zone of our court since it takes half of the inside of the 3 pointer.
This will be the biggest zone of our court since it takes half of the inside of the 3 pointer.
Second, the rectangles closest to the vertical border will all individually have a width of 1/12 and a height of 1/3. This is because in a real basketball court, the corner 3 pointer line is only 3 feet from the out of bounds line. This makes it the smallest zone in a basketball court; Therefore, it will be the smallest in our partition too. Short players and shooters can score from the corner 3 pointer because it will be one of their red zones, however, the other rectangles aren’t.
Next, the high, inside of the perimeter is where short players can score. This area has 3 separate rectangles, the ones on the outside have the measures of 1/4 by 1/3, and the middle rectangle will have the measures of 1/3 by 1/3. Only the middle rectangle will be a red zone, meaning short players will only be able to score from the middle rectangle.
Lastly, the centered, outside of the 3 point line, have 2 types of rectangles. The outer ones have individual measures of 1/4 by 1/6 and the middle rectangles have dimensions 1/3 by 1/6. The middle rectangle closest to the 3 point arch will be a shooter red zone.
Clearly, I have set these red zone’s like this for certain reasons: Tall players will score in the interior so I can show how their height gives them the ability to easily score over their defenders. Short players will score in the center midrange and from the corner 3’s to simulate how their height gives them speed and versatility so they can score a variety of spots. Shooters will only score from outside of the 3 point line: in the corners and the center. This is so I can simulate how they have more shooting range but also so I can differentiate them from short players.
Here, I make the rectangles for each players Red Zones based on their player profiles (tall player, short player, shooter):
In[]:=
allRedZonesIndex=<|"TallPlayerZone"->{Rectangle[{1/12,0},{11/12,1/3}]},"ShooterPlayerRedZone"->{Rectangle[{1/3,1/3},{2/3,2/3}],Rectangle[{0,0},{1/12,1/3}],Rectangle[{11/12,0},{1,1/3}]},"ShooterRedZone"->{Rectangle[{1/3,2/3},{2/3,5/6}],Rectangle[{0,0},{1/12,1/3}],Rectangle[{11/12,0},{1,1/3}]}|>;
Generates the red zones for each player profile for any court length or height given:
In[]:=
generateRedZones[courtLength_Integer,courthHeight_Integer]:=<|"TallPlayerZone"->{Rectangle[{courtLength*1/12,0},{courtLength*11/12,courthHeight*1/3}]},"ShooterPlayerRedZone"->{Rectangle[{courtLength*1/3,courthHeight*1/3},{courtLength*2/3,courthHeight*2/3}],Rectangle[{0,0},{courtLength*1/12,courthHeight*1/3}],Rectangle[{courtLength*11/12,0},{courtLength,courthHeight*1/3}]},"ShooterRedZone"->{Rectangle[{courtLength*1/3,courthHeight*2/3},{courtLength*2/3,courthHeight*5/6}],Rectangle[{0,0},{courtLength*1/12,courthHeight*1/3}],Rectangle[{courtLength*11/12,0},{courtLength,courthHeight*1/3}]}|>
Generate Remaining Zones
Generate Remaining Zones
Once I have our red zones, I have to create our remaining zones. As mentioned in the previous section, some of the zones aren’t red zones, however, they are still important because I need them to keep symmetry and ratios clear on the court. I could also see them as “cold zones”, since attackers do not score from here.
I fill the rest of the court with other rectangles that partition the court symmetrically in relation to the Y-axis. These would be the coordinates for a 1:1 square:
In[]:=
remainingZones={Blue,Rectangle[{0,1/3},{1/12,2/3}],Blue,Rectangle[{0,2/3},{1/12,3/3}],Blue,Rectangle[{1/12,1/3},{1/3,2/3}],Blue,Rectangle[{2/3,1/3},{11/12,2/3}],Blue,Rectangle[{11/12,1/3},{1,2/3}],Blue,Rectangle[{11/12,2/3},{1,3/3}],Blue,Rectangle[{1/12,2/3},{1/3,5/6}],Blue,Rectangle[{11/12,2/3},{2/3,5/6}],Blue,Rectangle[{1/12,5/6},{1/3,1}],Blue,Rectangle[{11/12,5/6},{2/3,1}],Blue,Rectangle[{1/3,5/6},{2/3,1}]};
Generates the remaining zones for any court length or height given:
Show Full Court Partitions
Show Full Court Partitions
I combine the zones but only show the edges so I can see the partitions of our court:
Shows the court partitions:
Shows the court partitions for different court lengths and widths:
Show Full Court Zones
Show Full Court Zones
I get this once I combine the red zones and the remaining zones and show them on the court. This shows how our partition keeps the ratios and symmetry:
Generates the court with the zones for any court dimensions given:
Shows the court zones for 3 different court dimensions:
These tests show how our partition keeps the ratios and symmetry even when I change the court length and width.
An interesting finding I had was that the function CircularArcThrough bugs and switches up the order and angle specifications of the court, if the width to height ratio is less than 1. This means that my 3 point arc and the paint summit won’t work for a court that’s longer than it is wide.
The bug for CircularArcThrough:
Applying a Coordinate System to the Court
Applying a Coordinate System to the Court
Court Partition
Court Partition
To build a dynamic 3vs3 basketball simulation, I first have to translate a continuous physical half-court into distinct, manageable regions. Basketball is inherently ruled by space; players cut to open spots to shake defenders and maximize scoring . Our simulation framework models this by defining geometric boundaries for specialized court areas, such as the basic floor spaces, “remaining zones,” and standard scoring hot-spots,“red zones,” unique to the 3 different player profiles .
To convert these shapes into a uniform grid layout, I implement a court division engine using localized helper functions.
To convert these shapes into a uniform grid layout, I implement a court division engine using localized helper functions.
Extracts the coordinates of the vertices of a given rectangle and rearranges it into a list:
Calculates the precise midpoints along each edge of a court zone rectangle:
Generate a grid of points inside specific court regions and look at the zone’s centroid to determine placement of the rest of the points in it:
Figure out the absolute width or height of any court zone rectangle:
I aggregate every zone on the court by combining the remaining zones and the red zones and process them into a list of coordinates: this makes exactly 90 points, distributed across the basketball court grid.
Grabs all rectangles from the list of court zones:
Grabs all rectangles from the list of court zones for any court length and height:
Evaluates widths to exclude points that are crowded in thin rectangles or lie boundary lines:
Grid Points
Grid Points
I have the partitions and our zones, however, I haven’t created the “board” that the players will move on. Consequently, I created a grid of points that is neatly distributed around the court.
How I made the points :
1
.Placed all the rectangles into one list.
2
.Found the centroid of a rectangle.
3
.Found the width and height of the rectangle.
4
.Found the four corners of the rectangle.
5
.Made a new empty list for the new points I are created.
6
.Looked at each of these features of the rectangles
7
.Displayed the graphics
I make our point grid for any given length and height and store it as “gridPoints”:
Shows the grid points for our 1 by 1 court:
I made the court in this way because that way it will have certain geometric logic and it will be dense in regions needed. For example, it is dense in the middle of the court but not on the outer zones. This helps because players will have to move to the scoring zones rather than the edges.
Shows the grid points for any court dimensions given:
Grid points for a 5 by 11 court:
Court Graph
Court Graph
While a list of 90 points establishes positions, it lacks connectivity. The data structure does not natively know how the points relate to each other . To turn this space into an active playing surface, I transform the point grid into a functional network graph (courtGraph):
Maps my court grid back to specific zones. Goes through my 90 point grid and identifies which grid point indices belong inside a “Red Zone”:
Compute what vertex points are in each red zone for any court dimensions:
Calculate what the 5 nearest points are to a vertex and connect them with a segment:
Generates a list of rules that maps each coordinate on the court grid to a unique index number for any court length and height:
Converts the grid connections from coordinates into an integer vertex, then deletes any duplicate or accidental lines:
Stores our list of vertex connections
Shows our graph for our 1 by 1 square:
◼
How the Graph was Constructed:
◼
Proximity Analysis: I map each coordinate pair to its 5 closest neighbors using the Nearest function.
◼
Path Formulation: These links are mapped out as multiple direction connections (UndirectedEdge).
◼
Integer Indexing: To avoid computing complex geometrical computations, the coordinates are transformed into indexed vertexes, 1 through 90.
◼
Self-Loop Filtering: I apply DeleteCases to systematically take out self connecting loops (UndirectedEdge[x_, x_]), forcing elements to move across the network instead of looping endlessly on a single vertex.
◼
Utility : How is the Graph Useful for Our Simulation Game?
Our system rules mandate that dribbling must occur incrementally across adjacent points . By passing a player’ s vertex’s location through AdjacencyList[courtGraph, currentPosition], the software instantly finds the correct neighboring locations. This lets the ball handler move step by step without breaking boundaries . Also, when running strategies like “GiveAndGo” or a “VCut”, attackers need to move toward their target vertex’s . Because the court is compiled as a network graph, I can use graph functions in wolfram to find these paths.
Shows the court graph for any given court length and height:
Moving the Players
Moving the Players
Location Updater Attacker
Location Updater Attacker
Appends the destination of the shortest path to the list under the player’s specific history key within the game state association:
Returns a list of integer vertexes because it shows the path the player is taking to get to their target location:
Shows the animation of the player’s path on a 1 by 1 square:
Shows the animation of the player’s path on a 15 by 9 rectangle:
Strategy
Strategy
Context
Context
In basketball, plays are the most efficient ways to make space and score. However, I want to implement the simplest yet most effective strategy in basketball. After some research I found the give and go. The give and go is one of the best plays in basketball because it uses a defender’s own eyes against them. The moment a player passes the ball, the defender almost always turns their head to watch where it goes. By sprinting to the hoop the exact second the ball leaves their hands, the passer gets an easy step on their defender. Since basketball teams spread out across the court to guard every zone, the paint is often wide open, leading to an easy shot, layup or dunk before the defense can help. By applying this simple strategy to our algorithm I can simulate the efficiency of the play on our court graph.
Algorithm
Algorithm
Our strategy relies on a continuous loop that first checks for ball possession before executing the tactical play. By comparing the vertex locations of the ball and the attacking player, the system determines if the offense still has the ball; If they don’t it immediately registers as a turnover. When possession is with the attackers, the offensive strategy activates only two players, the first as the primary ball handler and the second as the receiver, while placing the ball to the handler’s initial vertex. Then it executes a classic give-and-go: the first attacker calculates the shortest path to the target vertex, and the ball’s trajectory is updated to follow them, pass to the second attacker, and then a final pass to meet the first attacker cutting toward the target. To keep track of our team’s passing, a global counter automatically adds one to the passing total every time the ball handler changes.
References
References
Project Inspiration
Project Inspiration
Strategies
Strategies
Court Measurements
Court Measurements
Acknowledgements
Acknowledgements
I want to thank Stephen Wolfram for this amazing program. Wolfram High School Summer Research Program was really an extremely enriching experience for me. I would like to thank my mentor Angel Rojas for all of his support and Megan for all of their help with my code. Also, thank you to my TA Max for helping me persevere. Lastly, thank you to Willem Nielsen for meeting with me and giving me interesting ideas.
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Simulating 3 vs. 3 basketball on a 2D point graph to find and create optimal strategies
by Gustavo Lievano
Wolfram Community, STAFF PICKS, July 9, 2026
https://community.wolfram.com/groups/-/m/t/3753567
by Gustavo Lievano
Wolfram Community, STAFF PICKS, July 9, 2026
https://community.wolfram.com/groups/-/m/t/3753567