pingv4
A high-performance Connect Four library with a graphical game interface and bot framework.
Installation
pip install pingv4
Note: Python 3.9+ required
Quick Start
Play a Game
from pingv4 import Connect4Game, MinimaxBot
# Human vs Human
game = Connect4Game()
game.run()
# Human vs Bot
game = Connect4Game(player1=None, player2=MinimaxBot)
game.run()
# Bot vs Bot
game = Connect4Game(player1=MinimaxBot, player2=MinimaxBot)
game.run()
Use the Board Directly
from pingv4 import ConnectFourBoard, CellState
board = ConnectFourBoard()
# Make moves (returns a new board - immutable!)
board = board.make_move(3) # Red plays center
board = board.make_move(3) # Yellow plays center
board = board.make_move(2) # Red plays left of center
# Check game state
print(board.is_in_progress) # True
print(board.current_player) # CellState.Yellow
print(board.get_valid_moves()) # [0, 1, 2, 3, 4, 5, 6]
# Access cells (column-major: board[col, row])
print(board[3, 0]) # CellState.Red
print(board[3, 1]) # CellState.Yellow
# Print the board
print(board)
API Reference
CellState
An enum representing the state of a cell.
from pingv4 import CellState
CellState.Red # Red player (plays first)
CellState.Yellow # Yellow player
ConnectFourBoard
The core game board class. Immutable - all operations return new board instances.
Creating a Board
board = ConnectFourBoard() # Creates an empty 6x7 board
Properties
| Property | Type | Description |
|---|---|---|
num_rows |
int |
Number of rows (6) |
num_cols |
int |
Number of columns (7) |
current_player |
CellState | None |
Current player, or None if game over |
is_in_progress |
bool |
True if game is still ongoing |
is_victory |
bool |
True if a player has won |
is_draw |
bool |
True if the board is full with no winner |
winner |
CellState | None |
The winning player, or None |
column_heights |
list[int] |
Number of pieces in each column |
hash |
int |
Deterministic hash for the board state |
cell_states |
list[list[CellState | None]] |
All cells (column-major) |
Methods
# Get valid moves (columns that aren't full)
moves: list[int] = board.get_valid_moves()
# Make a move (returns NEW board)
new_board = board.make_move(col_idx) # col_idx: 0-6
# Access a cell (column-major!)
cell = board[col, row] # col: 0-6, row: 0-5 (bottom to top)
⚠️ Column-Major Access: Board indexing is
board[column, row], notboard[row, column].
Example: Game Loop
from pingv4 import ConnectFourBoard
board = ConnectFourBoard()
while board.is_in_progress:
move = int(input(f"{board.current_player}'s turn. Column (0-6): "))
if move in board.get_valid_moves():
board = board.make_move(move)
print(board)
if board.is_victory:
print(f"{board.winner} wins!")
else:
print("It's a draw!")
Connect4Game
A pygame-based graphical game interface.
from pingv4 import Connect4Game, GameConfig, MinimaxBot
# Basic usage
game = Connect4Game(
player1=None, # Human player
player2=MinimaxBot, # Bot class
config=GameConfig() # Optional configuration
)
game.run()
Constructor Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
player1 |
PlayerConfig |
None |
First player (see below) |
player2 |
PlayerConfig |
None |
Second player |
config |
GameConfig |
GameConfig() |
Game settings |
PlayerConfig can be:
None— Human player (manual input)- Bot class (e.g.,
MinimaxBot,RandomBot) — Will be instantiated automatically
Controls
| Key | Action |
|---|---|
| Click | Place piece (human turn) |
R |
Restart game |
ESC |
Quit |
GameConfig
Frozen Pydantic model for game configuration.
from pingv4 import GameConfig
config = GameConfig(
bot_delay_seconds=0.5, # Delay before bot moves (default: 1.0)
animation_speed=35, # Piece falling speed (default: 25)
window_width=700, # Window width in pixels
window_height=700, # Window height in pixels
cell_size=80, # Size of each cell
background_color=(30, 30, 40),
board_color=(0, 80, 180),
red_color=(220, 50, 50),
yellow_color=(240, 220, 50),
)
Creating Custom Bots
Extend AbstractBot to create your own Connect Four AI:
from pingv4 import AbstractBot, ConnectFourBoard, CellState
class MyBot(AbstractBot):
@property
def strategy_name(self) -> str:
return "My Custom Bot"
@property
def author_name(self) -> str:
return "Your Name"
@property
def author_netid(self) -> str:
return "your_id"
def get_move(self, board: ConnectFourBoard) -> int:
"""Return a column index (0-6) for your move."""
valid_moves = board.get_valid_moves()
# Your strategy here!
# Example: prefer center columns
for col in [3, 2, 4, 1, 5, 0, 6]:
if col in valid_moves:
return col
return valid_moves[0]
Using Your Bot
from pingv4 import Connect4Game
game = Connect4Game(player1=MyBot, player2=None)
game.run()
Bot Interface
Your bot receives a ConnectFourBoard and must return a valid column index.
def get_move(self, board: ConnectFourBoard) -> int:
# Useful properties:
board.current_player # Your color (CellState.Red or CellState.Yellow)
board.get_valid_moves() # List of valid columns
board.column_heights # How full each column is
board.hash # For transposition tables
# Simulate moves:
future = board.make_move(col) # Returns new board
# Check outcomes:
future.is_victory # Did someone win?
future.winner # Who won?
return column_index # 0-6
Built-in Bots
RandomBot
Plays random valid moves. Useful for testing.
from pingv4 import RandomBot
MinimaxBot
Strong AI using minimax with alpha-beta pruning.
from pingv4 import MinimaxBot
# Default depth is 6
game = Connect4Game(player1=MinimaxBot, player2=MinimaxBot)
Features:
- Alpha-beta pruning
- Transposition tables (using
board.hash) - Center-preference move ordering
- Positional evaluation
Tips for Bot Development
Use the Hash for Caching
The board.hash property is highly optimized. Use it for transposition tables:
cache = {}
def evaluate(board):
if board.hash in cache:
return cache[board.hash]
score = expensive_calculation(board)
cache[board.hash] = score
return score
Board is Immutable
make_move() returns a new board. The original is unchanged:
board1 = ConnectFourBoard()
board2 = board1.make_move(3)
board1[3, 0] # None (unchanged)
board2[3, 0] # CellState.Red
Column-Major Access
Remember: it's board[column, row], not board[row, column].
# Check if column 3 has a red piece at the bottom
if board[3, 0] == CellState.Red:
...
Metadata
Release files for pingv4 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pingv4-0.1.3.tar.gz | 43.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pingv4-0.1.3-cp39-abi3-manylinux_2_34_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.34+ x86-64 | Details |
Total release size: 283.2 kB
Release files / pingv4-0.1.3.tar.gz
| Download URL | pingv4-0.1.3.tar.gz |
|---|---|
| Size | 43.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9555f69cc7cc3851f323ad333c08404f64164b382195111ef804e4ddbb51cf07
|
|
BLAKE2b-256 checksum How to use checksums |
591ccfc524dcf0aeed1100b54b6d8c0921b55c0a49d3998516548482c2f4ba56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.9.3
|
Release files / pingv4-0.1.3-cp39-abi3-manylinux_2_34_x86_64.whl
| Download URL | pingv4-0.1.3-cp39-abi3-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 240.2 kB |
| Tags | CPython 3.9 Linux glibc 2.34+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4a629af30c6c99e7b32d5266cc1cea54d900bcf5a6adb141d8743d7583a95d31
|
|
BLAKE2b-256 checksum How to use checksums |
c0a0506ce08c7effd449f02a398a70027dcff74a5fb32ef0d59d672cf6fe5346
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.9.3
|