Skip to main content

What is Pica y Fija?

Pica y Fija is a real-time multiplayer guessing game where two players compete to discover each other’s secret 4-digit number. The game combines logic, deduction, and strategy in an engaging head-to-head format.
Pica y Fija is also known as “Bulls and Cows” or “Mastermind” in other regions. The name comes from the Spanish words for the scoring system: Picas (correct digits in wrong positions) and Fijas (correct digits in correct positions).

How It Works

The game follows a simple but addictive gameplay loop:
  1. Setup: Two players join a game room
  2. Secret Selection: Each player chooses a secret 4-digit number (all digits must be unique)
  3. Turn-Based Guessing: Players alternate making guesses about their opponent’s secret number
  4. Feedback System: After each guess, players receive feedback:
    • Fijas: How many digits are correct and in the correct position
    • Picas: How many digits are correct but in the wrong position
  5. Victory: The first player to guess all 4 digits correctly (4 Fijas) wins!

Key Features

Real-Time Multiplayer

Built with Socket.IO for instant, bidirectional communication between players. The game uses WebSocket transport for minimal latency:
const socket = io(window.location.origin, { transports: ['websocket'] });

Flexible Room System

Players can create and join games in multiple ways:
  • Create Private Rooms: Generate a unique room code to share with friends
  • Public Matchmaking: Join available public rooms automatically
  • Join by Code: Enter a specific room code to join a friend’s game

Configurable Game Options

Room hosts can customize the game experience:
  • Turn Timer: Set time limits per turn (configurable in seconds)
  • Public/Private: Choose whether the room appears in matchmaking
  • Approval Requirements: Option to require host approval for joiners
socket.emit('crearSala', { 
  tiempoTurno: 60,
  publica: true,
  requiereAprobacion: false 
});

Turn-Based System with Timers

Each player has a limited amount of time to make their guess. If time runs out, the turn automatically passes to the opponent:
if (timeLeft <= 0) {
  socket.emit('pasarTurnoPorTiempo');
}

Visual Feedback & Audio

Enhanced user experience with:
  • Color-coded turn indicators (white for your turns, orange for opponent)
  • Real-time game log showing all events
  • Audio cues for different game events (turn start, secret submission, victory/defeat)
  • Scrollable results table showing complete game history

Input Validation

The game enforces strict validation rules:
  • Must be exactly 4 digits
  • All digits must be unique (no repeated digits)
  • Server-side validation prevents invalid moves
if (!/^\d{4}$/.test(secret) || new Set(secret).size !== 4) {
  socket.emit('error', 'El número debe tener 4 cifras diferentes');
}

Technology Stack

Backend

  • Node.js with Express.js
  • Socket.IO for real-time communication
  • HTTP Server for WebSocket upgrades

Frontend

  • Vanilla JavaScript (no framework dependencies)
  • Bootstrap 5 for responsive UI
  • Font Awesome for icons
  • Socket.IO Client for server connection

Game Logic Example

The core scoring algorithm compares the guess against the secret number:
function getPicasFijas(secret, guess) {
  let fijas = 0, picas = 0;
  for (let i = 0; i < 4; i++) {
    if (guess[i] === secret[i]) fijas++;
    else if (secret.includes(guess[i])) picas++;
  }
  return { fijas, picas };
}
The game uses a simple but effective algorithm: for each position, if the digits match exactly, it’s a Fija. If the digit exists in the secret but in a different position, it’s a Pica.

Architecture Overview

The application uses a client-server architecture:
  • Server (server.js): Manages game rooms, validates moves, calculates scores, and broadcasts results
  • Client (index.html + inline JavaScript): Handles UI, user input, and Socket.IO communication
  • State Management: Room state is maintained server-side with player sockets, secrets, and turn tracking
rooms[code] = {
  host: socket,
  players: [socket],
  secrets: {},
  turn: 0,
  turnCounts: [1, 1],
  options: { tiempoTurno, publica, requiereAprobacion },
  gameOver: false
};

Getting Started

Ready to play? Check out the Quickstart Guide to learn how to create or join a game and start guessing!

Quickstart

Learn how to play Pica y Fija in under 5 minutes

Build docs developers (and LLMs) love