Loading

Execution Mode

Live: will automatically execute upon every character typed (warning: could result in issues if you have intensive or partially-completed code that results in an infinite loop)

Exited code editor: will automatically execute code when the code editor loses focus - i.e. when you click outside of the code editor

Run on click: code will only be executed when you click the triangular run/play button

Programs

Choose from a number of pre-made programs or create your own

Modifying a pre-made program will automatically create a new program, ensuring the original & modified version are available

Create Trace Table

Automatically create trace tables for your code

Can use the BREAKPOINT keyword to add breakpoints at specific parts of your program

Use TRACE_NEXT_ROW to force new row to be created in trace table

Autoformat Code

Toggle original/formatted code

Formatted code will insert new lines, indentation and apply consistent styling rules

Note: you can even try writing your entire program on one line...and it should still run and be formatted correctly :)

Loading

Load a previously-saved pseudocode file (.pseudo default extension)

Download

Download a .pseudo file for future use

Note: programs will be saved periodically (every 10 seconds) to your browser's storage if changes are made - this means you can access your programs across multiple tabs

Upload

Save your program for public-viewing by anyone

Sharing

Share a direct link containing your code - your code will be contained in the URL and NOT stored on the server

Alternatively, you can select the upload option to upload your code publicly to the server

Fullscreen

Toggle between regular and fullscreen mode

Note: pressing FN/F11/ESC keys isn't recommended, since they can't be detected by us, hence we can't apply the desired styles. Hence why this toggle button exists. Alternatively, CTRL + M (minimise <-> maximise) will also work

Add Favourite

Add this code as a favourite you can view later

No errors ✅

Error Checks

The site aims to enforce the statically-typed nature of pseudocode - i.e. assigning a STRING to an INTEGER variable should be forbidden. Some combinations are allowed, however - such as assigning a CHAR to a STRING or an INTEGER to a REAL. Other additional checks to ensure valid pseudocode are also in place

The site has been well-tested and there aren't any bugs we are aware of, however, if you believe the site is incorrectly giving you an error & preventing your code from running, you can disable the error-checking

In such cases, please feel free to contact us

Note that it is not possible to disable fatal error messages such as syntax errors, runtime errors etc

Subroutine Signature Hints

If enabled, the following information will be shown:

  • Keyword/Identifier/Module Name Suggestions
  • Subroutine parameters & types
  • Return types
  • Subroutine descriptions
  • Examples

Switch Program Shortcuts

Choose whether CTRL + SHIFT + LEFT/RIGHT should navigate to the previous program - can be disabled to prevent accidental triggering

Toggle Keyboard Shortcuts

Enable or disable this website's additional keyboard shortcuts (switch program, change font size, code execution etc) - note: standard editor & browser shortcuts will still apply

Wait for Tips

Will show the loading screen until at least the tip (hint) has been displayed, even if the site is fully loaded. Disabling this can hence make the editor screen appear faster, if the page is ready

Max Execution Time

To prevent infinite loops resulting in the page becoming unresponsive, code will automatically terminate if this value (in seconds) is exceeded

If you have a legitimate long-running program, you can obviously set this to a high value - alternatively, setting to -1 will disable this check

IGCSE Syllabus (Pseudocode p33) O-Level Syllabus (Pseudocode p33) A-Level Pseudocode Guide Report Bugs
YouTube Tutorials Discord Help AssemblyCode
Demos🧑🏻‍🏫 Keyword List📜 Monthly Challenge: Getting...📆
{"0":"Algorithms","1":"Selection","2":"Iteration","3":"Arrays","4":"Records","5":"ENUMs","6":"Custom Modules","7":"Files","8":"Object-Oriented Programming","9":"Abstract Data Types","10":"Sets","11":"Pointers","12":"Recursion","13":"Exam Questions","14":"Games","15":"Mathematics","16":"Art","17":"Utilities","18":"Other"}

Welcome to Pseudocode Pro

This site was developed to solve the problems of students either being completely stuck with pseudocode, or attempting a solution, but having no way of actually validating if it would work (other than a manual trace table). This site supports the entire Cambridge IGCSE (0478), O-Level (2210) and 9618 A-Level pseudocode specifications from the guide/syllabus, with extension modules supporting sound, canvas, events, custom html etc

Below are lists of both the currently support pseudocode and general website features:

  • 📦 Variables & Constants
  • ➕ Arithmetic & Logical Operators
  • 📥📤 INPUT & OUTPUT
  • ❓❌ IF/ELSE & CASE
  • 🔁 FOR/WHILE/REPEAT...UNTIL Loops
  • 🔧 FUNCTIONS & PROCEDURES
  • 🔢 BYVAL & BYREF
  • 🔢 ARRAYs
  • 📒 TYPEs (Records & Enums)
  • 📄 File Handling (Text & RANDOM)
  • 🧩 Object-Oriented Programming
  • 🪣 Sets
  • 👉 Pointers
  • --- Extra Non-Syllabus Features ---
  • 🔊 Sound
  • 🎨 Canvas
  • 🖲️ Events
  • 🖥️ Custom HTML
  • 🌟 Code-suggestions/auto-complete
  • 🌈 Syntax Highlighting
  • 🚩 Error messages & positions
  • 💾 Loading/saving/sharing/uploading programs
  • 🥇 Interesting practice activities of various difficulties (updated daily and will have 500+ total)
  • 📆 Monthly challenges
  • 📖 Past paper PDFs & bundles
  • ✨ Pretty-printing
  • ⌨️ Keyboard shortcuts
  • 🎨 Changing appearance - font size, theme, layout etc
  • 📺 Fullscreen & 📱 mobile support
  • 🎓 Syllabus-specific behaviour

Additional programs uploaded by the community can be found on the search page.

While you are here, why not try one of the many - and ever increasing list of - pseudocode coding challenges.

To support hosting & domain costs, for $2, a premium account can be purchased - this has the following benefits:

Those last 2 features are currently in progress, so an extra 3 months free will be given to anyone who buys a license now to acknowledge this

For any issues, feature requests, comments etc, you can contact me

Token List

Work in progress: some buttons currently don't work...just select "All"

Token Description Example Parameters

Thanks for using the site - I hope you enjoy it and if you do, it would mean a lot if you could share it with your friends too :)

Drag & drop code or data files here

{"c":"\/\/ * Code Author: BalaM314\n\/\/ * Date: 2025\/01\/10\n\/\/ * Description: Version 1.0.1\r\n\/\/ Submitted to Pseudocode.pro game jam.\r\n\/\/ Shift+click to flag.\r\n\/\/ Recommended difficulty: 7.\r\n\/\/ Chording not supported.\r\n\/\/ Board size cannot be edited while running due to engine limitations (no dynamically-sized arrays).\r\n\/\/ \r\n\/\/ v0.9.0: Prototype\r\n\/\/ v1.0.0: Added replay, start safety, colors, difficulty prompt\r\n\/\/ v1.0.1: Fixed bug in Chrome browsers\n\/\/ * Categories: Games\n\n\/\/ * Code Author: BalaM314\r\n\/\/ * Date: 2025\/01\/09\r\n\/\/ * Description: Submitted to Pseudocode.pro game jam.\r\n\/\/ Shift+click to flag.\r\n\/\/ Recommended difficulty: 7.\r\n\/\/ Chording not supported.\r\n\/\/ Board size cannot be edited while running due to engine limitations (no dynamically-sized arrays).\r\n\/\/ \r\n\/\/ * Categories: Games\r\n\r\n\/\/Minesweeper v1.0.1\r\n\/\/by BalaM314\r\n\/\/Submitted to pseudocode.pro game jam January 2025\r\n\/\/SET_MAX_EXECUTION_TIME=-1\r\n\r\n\/\/Utils\r\nTYPE Pos2\r\n DECLARE x: INTEGER\r\n DECLARE y: INTEGER\r\nENDTYPE\r\n\r\nTYPE BoundingBox\r\n DECLARE x, y, width, height : REAL\r\nENDTYPE\r\n\r\nPROCEDURE incrementChecked(BYREF arr: ARRAY OF INTEGER, BYVAL x, y: INTEGER)\r\n IF x >= 1 AND x <= LENGTH(arr) AND y >= 1 AND y <= LENGTH(arr[x]) THEN\r\n arr[x, y] <- arr[x, y] + 1\r\n ENDIF\r\nENDPROCEDURE\r\n\r\nFUNCTION inBounds(BYREF arr: ARRAY OF BOOLEAN, BYVAL x, y: INTEGER) RETURNS BOOLEAN\r\n RETURN x >= 1 AND x <= LENGTH(arr) AND y >= 1 AND y <= LENGTH(arr[x])\r\nENDFUNCTION\r\n\r\nFUNCTION mouseInRect(x, y, width, height: INTEGER) RETURNS BOOLEAN\r\n RETURN mouse.x > x AND mouse.y > y AND mouse.x < x + width AND mouse.y < y + height\r\nENDFUNCTION\r\n\r\n\/\/Canvas setup\r\nCONSTANT canvas_w = 800\r\nCONSTANT canvas_h = 600\r\nCONSTANT center_x = canvas_w \/ 2\r\nCONSTANT center_y = canvas_h \/ 2\r\nCONSTANT cid = \"Game\"\r\nCALL CREATECANVAS(cid, canvas_w, canvas_h)\r\n\r\n\/\/Variables\r\nDECLARE mouse: Pos2\r\nDECLARE gameStarted, gameFinished: INTEGER\r\nCONSTANT ring_size = 15\r\nCONSTANT board_w = 24\r\nCONSTANT board_h = 18\r\nCONSTANT tile_size = 25\r\nCONSTANT mine_count_size = 24\r\n\r\n\/\/State\r\nTYPE StateType = (playing, win, lose)\r\nTYPE GameState\r\n DECLARE mines: ARRAY[1:board_w, 1:board_h] OF BOOLEAN\r\n DECLARE flags: ARRAY[1:board_w, 1:board_h] OF BOOLEAN\r\n DECLARE mineCount: ARRAY[1:board_w, 1:board_h] OF INTEGER\r\n DECLARE showTile: ARRAY[1:board_w, 1:board_h] OF BOOLEAN\r\n DECLARE redTile: ARRAY[1:board_w, 1:board_h] OF BOOLEAN\r\n DECLARE type: StateType\r\n DECLARE mineChance: REAL\r\n DECLARE firstClickDone: BOOLEAN\r\nENDTYPE\r\nDECLARE state: GameState\r\nPROCEDURE initBoard(mineChance: REAL)\r\n FOR x <- 1 TO board_w\r\n FOR y <- 1 TO board_h\r\n state.mineCount[x, y] <- 0\r\n state.showTile[x, y] <- FALSE\r\n state.flags[x, y] <- FALSE\r\n state.redTile[x, y] <- FALSE\r\n NEXT y\r\n NEXT x\r\n FOR x <- 1 TO board_w\r\n FOR y <- 1 TO board_h\r\n state.mines[x, y] <- RANDOM() < mineChance\r\n IF state.mines[x, y] THEN\r\n CALL incrementChecked(state.mineCount, x - 1, y - 1)\r\n CALL incrementChecked(state.mineCount, x, y - 1)\r\n CALL incrementChecked(state.mineCount, x + 1, y - 1)\r\n CALL incrementChecked(state.mineCount, x - 1, y)\r\n CALL incrementChecked(state.mineCount, x, y)\r\n CALL incrementChecked(state.mineCount, x + 1, y)\r\n CALL incrementChecked(state.mineCount, x - 1, y + 1)\r\n CALL incrementChecked(state.mineCount, x, y + 1)\r\n CALL incrementChecked(state.mineCount, x + 1, y + 1)\r\n ENDIF\r\n NEXT y\r\n NEXT x\r\n state.type <- StateType.playing\r\n state.firstClickDone <- FALSE\r\n state.mineChance <- mineChance\r\n CALL drawGame()\r\nENDPROCEDURE\r\n\r\n\/\/Display\r\nPROCEDURE drawBoard()\r\n FOR x <- 1 TO board_w\r\n FOR y <- 1 TO board_h\r\n IF state.type <> StateType.playing OR state.showTile[x, y] THEN\r\n CALL DRAWRECT(cid, x * tile_size, y * tile_size, tile_size, tile_size, \"white\", \"black\", 1)\r\n IF state.mines[x, y] THEN\r\n IF state.type = StateType.win THEN\r\n CALL DRAWCIRCLE(cid, (x + 0.5) * tile_size, (y + 0.5) * tile_size, tile_size \/ 2 - 2, \"gray\", \"black\", 1)\r\n ELSE\r\n CALL DRAWCIRCLE(cid, (x + 0.5) * tile_size, (y + 0.5) * tile_size, tile_size \/ 2 - 2, \"red\", \"black\", 1)\r\n ENDIF\r\n ELSE IF state.mineCount[x, y] <> 0 THEN\r\n CALL DRAWTEXT(cid, NUM_TO_STR(state.mineCount[x, y]), \"center\", (x + 0.5) * tile_size, (y + 0.75) * tile_size, mine_count_size, \"monospace\", numberColor(state.mineCount[x, y]), \"\", 0)\r\n ENDIF ENDIF\r\n ELSE\r\n IF NOT state.firstClickDone AND state.redTile[x, y] THEN\r\n CALL DRAWRECT(cid, x * tile_size, y * tile_size, tile_size, tile_size, \"#A88\", \"black\", 1)\r\n ELSE\r\n CALL DRAWRECT(cid, x * tile_size, y * tile_size, tile_size, tile_size, \"gray\", \"black\", 1)\r\n ENDIF\r\n IF state.flags[x, y] THEN\r\n CALL DRAWTEXT(cid, \"\ud83d\udea9\", \"center\", (x + 0.5) * tile_size, (y + 0.75) * tile_size, mine_count_size, \"monospace\", \"black\", \"\", 0)\r\n ENDIF\r\n ENDIF\r\n NEXT y\r\n NEXT x\r\nENDPROCEDURE\r\nPROCEDURE drawGame()\r\n CALL DRAWRECT(cid, 0, 0, canvas_w, canvas_h, \"#000\", \"\", 0)\r\n CALL drawBoard()\r\n DECLARE belowBoard: INTEGER\r\n belowBoard <- (board_h + 1) * tile_size\r\n DECLARE difficulty: STRING\r\n difficulty <- NUM_TO_STR(state.mineChance * 40)\r\n IF state.type = StateType.lose THEN\r\n CALL DRAWTEXT(cid, \"You Lose\", \"center\", center_x, belowBoard + 40, 30, \"monospace\", \"red\", \"white\", 2)\r\n CALL DRAWRECT(cid, center_x - 100, belowBoard + 53, 200, 40, \"gray\", \"\", 0)\r\n CALL DRAWTEXT(cid, \"Play Again\", \"center\", center_x, belowBoard + 80, 30, \"monospace\", \"white\", \"\", 0)\r\n ELSE IF state.type = StateType.playing THEN\r\n CALL DRAWTEXT(cid, \"Minesweeper\", \"center\", center_x, belowBoard + 40, 30, \"monospace\", \"white\", \"white\", 2)\r\n CALL DRAWTEXT(cid, \"Difficulty: \" & difficulty & \" Time: \" & NUM_TO_STR((TIME(0) - gameStarted) DIV 1000) & \"s\", \"center\", center_x, belowBoard + 80, 30, \"monospace\", \"white\", \"white\", 2)\r\n ELSE IF state.type = StateType.win THEN\r\n CALL DRAWTEXT(cid, \"You Win (\" & NUM_TO_STR((gameFinished - gameStarted) DIV 1000) & \"s, difficulty \" & difficulty & \")\", \"center\", center_x, belowBoard + 40, 30, \"monospace\", \"lime\", \"white\", 2)\r\n CALL DRAWRECT(cid, center_x - 100, belowBoard + 53, 200, 40, \"gray\", \"\", 0)\r\n CALL DRAWTEXT(cid, \"play again\", \"center\", center_x, belowBoard + 80, 30, \"monospace\", \"white\", \"\", 0)\r\n ENDIF ENDIF ENDIF\r\nENDPROCEDURE\r\nFUNCTION numberColor(n:INTEGER) RETURNS STRING\r\n CASE OF n\r\n 1: RETURN \"#1A1\"\r\n 2: RETURN \"#0AA\"\r\n 3: RETURN \"#00C\"\r\n 4: RETURN \"#A0A\"\r\n 5: RETURN \"#E90\"\r\n 6: RETURN \"#C77\"\r\n 7: RETURN \"#B11\"\r\n 8: RETURN \"#500\"\r\n OTHERWISE: RETURN \"#FFF\"\r\n ENDCASE\r\nENDFUNCTION\r\n\r\n\/\/Game logic\r\nPROCEDURE tileClicked(x, y: INTEGER, shift: BOOLEAN)\r\n IF inBounds(state.showTile, x, y) THEN\r\n IF shift THEN\r\n state.flags[x, y] <- NOT state.flags[x, y]\r\n ELSE\r\n IF state.flags[x, y] THEN\r\n state.flags[x, y] <- FALSE\r\n ELSE\r\n IF NOT state.firstClickDone AND (state.mines[x, y] OR state.mineCount[x, y] <> 0) THEN\r\n state.redTile[x, y] <- TRUE\r\n ELSE\r\n state.firstClickDone <- TRUE\r\n CALL revealTiles(x, y)\r\n IF state.mines[x, y] THEN\r\n state.type <- StateType.lose\r\n ENDIF\r\n IF state.type = StateType.playing AND checkWin() THEN\r\n state.type <- StateType.win\r\n gameFinished <- TIME(0)\r\n ENDIF\r\n ENDIF\r\n ENDIF\r\n ENDIF\r\n ENDIF\r\nENDPROCEDURE\r\n\r\nFUNCTION checkWin() RETURNS BOOLEAN\r\n FOR x <- 1 TO board_w\r\n FOR y <- 1 TO board_h\r\n IF NOT state.mines[x, y] AND NOT state.showTile[x, y] THEN\r\n RETURN FALSE\r\n ENDIF\r\n NEXT y\r\n NEXT x\r\n RETURN TRUE\r\nENDFUNCTION\r\n\r\nPROCEDURE revealTiles(x, y: INTEGER)\r\n IF inBounds(state.showTile, x, y) THEN\r\n IF NOT state.showTile[x, y] AND state.mineCount[x, y] = 0 THEN\r\n state.showTile[x, y] <- TRUE\r\n CALL revealTiles(x - 1, y - 1)\r\n CALL revealTiles(x, y - 1)\r\n CALL revealTiles(x + 1, y - 1)\r\n CALL revealTiles(x - 1, y)\r\n CALL revealTiles(x + 1, y)\r\n CALL revealTiles(x - 1, y + 1)\r\n CALL revealTiles(x, y + 1)\r\n CALL revealTiles(x + 1, y + 1)\r\n ELSE\r\n state.showTile[x, y] <- TRUE\r\n ENDIF\r\n ENDIF\r\nENDPROCEDURE\r\n\r\nEVENT CLICK\r\n DECLARE canvasBounds : BoundingBox\r\n canvasBounds <- GETCANVASBOUNDS(cid)\r\n mouse.x <- event.x - canvasBounds.x DIV 1\r\n mouse.y <- event.y - canvasBounds.y DIV 1\r\n IF mouse.x > 0 AND mouse.y > 0 AND mouse.x < canvas_w AND mouse.y < canvas_h THEN\r\n IF state.type = StateType.playing THEN\r\n CALL tileClicked(ROUND(mouse.x \/ tile_size - 0.5, 0), ROUND(mouse.y \/ tile_size - 0.5, 0), event.shiftKey)\r\n ELSE IF state.type = StateType.win OR state.type = StateType.lose THEN\r\n DECLARE belowBoard: INTEGER\r\n belowBoard <- (board_h + 1) * tile_size\r\n IF mouseInRect(center_x - 100, belowBoard + 53, 200, 40) THEN\r\n CALL initBoard(getDifficulty())\r\n ENDIF\r\n ENDIF ENDIF\r\n ENDIF\r\n CALL drawGame()\r\nENDEVENT\r\n\r\nFUNCTION getDifficulty() RETURNS REAL\r\n DECLARE difficulty: REAL\r\n OUTPUT \"Enter a difficulty between 1 and 10\"\r\n INPUT difficulty\r\n difficulty <- difficulty \/ 40\r\n gameStarted <- TIME(0)\r\n IF 0 <= difficulty AND difficulty <= 1 THEN\r\n RETURN difficulty\r\n ELSE\r\n RETURN 0.1\r\n ENDIF\r\nENDFUNCTION\r\n\r\nCALL initBoard(getDifficulty())","t":"Minesweeper"}
ALL