--- title: "Hex Movement Library" type: "article" slug: "hex-movement-library" url: "http://localhost/article/hex-movement-library/" markdown_url: "http://localhost/article/hex-movement-library.md" published_at: "2025-11-30T07:51:06+00:00" modified_at: "2026-06-21T23:21:47+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Recently I've been distracted by one of my other hobby, wargaming. There has been a discussion on USENET about freeware space combat games. Having designed one a few years back, I quickly did an ASCII version and posted it. This then lead to further distractions in that hobby. Feeling guilty about \"abandoning\" the QL, I…" category: - name: "QL Hacker's Journal" slug: "ql-hackers-journal" taxonomy: "category" url: "http://localhost/category/periodicals/ql-hackers-journal/" post_tag: - name: "Full Text" slug: "fulltext" taxonomy: "post_tag" url: "http://localhost/tag/fulltext/" - name: "QL" slug: "ql" taxonomy: "post_tag" url: "http://localhost/tag/ql/" - name: "Superbasic (programming language)" slug: "superbasic-programming-language" taxonomy: "post_tag" url: "http://localhost/tag/superbasic-programming-language/" - name: "Type-in program" slug: "type-in-program" taxonomy: "post_tag" url: "http://localhost/tag/type-in-program/" model: - name: "Sinclair QL" slug: "sinclair-ql" taxonomy: "model" url: "http://localhost/model/sinclair-ql/" indiv: - name: "Tim Swenson" slug: "tim-swenson" taxonomy: "indiv" url: "http://localhost/indiv/tim-swenson/" publication_r: id: 33686 title: "QL Hacker’s Journal" type: "periodical" url: "http://localhost/periodical/ql-hackers-journal/" authors_r: - name: "Tim Swenson" slug: "tim-swenson" taxonomy: "indiv" url: "http://localhost/indiv/tim-swenson/" issue: "15" issues_articles: - id: 61551 title: "QL Hacker’s Journal 15" type: "issue" url: "http://localhost/issue/ql-hackers-journal-15/" pubdate: "October 1993" archive_link: true --- # Hex Movement Library Recently I’ve been distracted by one of my other hobby, wargaming. There has been a discussion on USENET about freeware space combat games. Having designed one a few years back, I quickly did an ASCII version and posted it. This then lead to further distractions in that hobby. Feeling guilty about “abandoning” the QL, I wanted to come up with some program that would tie the two hobbies together. Most wargames are based on hex maps. One of the difficulties in putting wargames on a computer is the hex map system. A square map system is nothing more than a 2D array. But a hex map system, with each cell having 6 neighbors is takes some work. It’s workable with a square map, by extending the rules for what squares are “next” to the current square. After pondering over this, and pursuing how I would represent a hex map in an array, I discovered that I really don’t need to store the hex map, just a way of determining what hex was next to the current hex. Anything relating to what is in a hex can be stored in an array, looked up by the hex number. These routines will determine two things, what hex is next to the current hex (given any direction), and the distance (in hexes) between two hexes. Determining what hex is next to another hex was fairly easy. Finding the proper distance was a more challenging task. I first tried the distance formula used in square coordinate system. This had some flaws. I then tried a different approach based on simple common sense about hexes. This worked until I got back to the program the next day and THEN saw that it did not work. Back to the distance formula. After much plugging and chugging, plus some tinking with the distance formula, I found an algorithm that worked (at least in the cases that I tested). I found the general case that failed in the plain distance formula and found a fix for these cases. I’m pretty sure that it all works fine, but I have not tested all cases. The hex number system that I used came from my favorite wargame, [OGRE](https://www.sjgames.com/ogre/). I have not played with other numbering systems. Each hex number is two numbers combined, a column number and a row number. 0102 is column 01 and row 02. Below is a quick drawing of the numbering system. ``` __ / \ __/ Y \__ / \ / \ /|\ Hex X = 0102 / X \__/ Z \ | Hex Y = 0201 \ / \ / Hex Z = 0302 \__/ A \__/ N Hex A = 0202 \ / \__/ ``` ``` 100 DEFine FuNction even(num) 110 true = 1 : false = 0 120 IF (num MOD 2) = 0 THEN 130 RETurn true 140 ELSE 150 RETurn false 160 END IF 170 END DEFine 190 DEFine FuNction odd(num) 200 true = 1 : false = 0 210 IF (num MOD 2) > 0 THEN 220 RETurn true 230 ELSE 240 RETurn false 250 END IF 260 END DEFine 270 DEFine FuNction hex_north$(hex_num$) 280 LOCal column$, row, temp$ 290 column$ = hex_num$(1 TO 2) 300 row = hex_num$(3 TO 4) 310 row = row - 1 320 temp$ = row 330 IF LEN(temp$) = 1 THEN temp$="0"&temp$ 340 RETurn column$&temp$ 350 END DEFine 360 DEFine FuNction hex_south$(hex_num$) 370 LOCal column$, row, temp$ 380 column$ = hex_num$(1 TO 2) 390 row = hex_num$(3 TO 4) 400 row = row + 1 410 temp$ = row 420 IF LEN(temp$) = 1 THEN temp$="0"&temp$ 430 RETurn column$&temp$ 440 END DEFine 450 DEFine FuNction hex_ne$(hex_num$) 460 LOCal temp1$,temp2$,column,row 470 column = hex_num$(1 TO 2) 480 row = hex_num$(3 TO 4) 490 IF odd(column) THEN row=row-1 500 column=column+1 510 temp1$ = row 520 IF LEN(temp1$) = 1 THEN temp1$ = "0"&temp1$ 530 temp2$ = column 540 IF LEN(temp2$) = 1 THEN temp2$ = "0"&temp2$ 550 RETurn temp2$&temp1$ 560 END DEFine 570 DEFine FuNction hex_se$(hex_num$) 580 LOCal temp1$,temp2$,column,row 590 column = hex_num$(1 TO 2) 600 row = hex_num$(3 TO 4) 610 IF even(column) THEN row=row+1 620 column=column+1 630 temp1$ = row 640 IF LEN(temp1$) = 1 THEN temp1$ = "0"&temp1$ 650 temp2$ = column 660 IF LEN(temp2$) = 1 THEN temp2$ = "0"&temp2$ 670 RETurn temp2$&temp1$ 680 END DEFine 690 DEFine FuNction hex_nw$(hex_num$) 700 LOCal temp1$,temp2$,column,row 710 column = hex_num$(1 TO 2) 720 row = hex_num$(3 TO 4) 730 IF odd(column) THEN row=row-1 740 column=column-1 750 temp1$ = row 760 IF LEN(temp1$) = 1 THEN temp1$ = "0"&temp1$ 770 temp2$ = column 780 IF LEN(temp2$) = 1 THEN temp2$ = "0"&temp2$ 790 RETurn temp2$&temp1$ 800 END DEFine 810 DEFine FuNction hex_sw$(hex_num$) 820 LOCal temp1$,temp2$,column,row 830 column = hex_num$(1 TO 2) 840 row = hex_num$(3 TO 4) 850 IF even(column) THEN row=row+1 860 column=column-1 870 temp1$ = row 880 IF LEN(temp1$) = 1 THEN temp1$ = "0"&temp1$ 890 temp2$ = column 900 IF LEN(temp2$) = 1 THEN temp2$ = "0"&temp2$ 910 RETurn temp2$&temp1$ 920 END DEFine 930 DEFine FuNction hex_dist(hex1$,hex2$) 940 LOCal temp1, temp2, col1, col2, row1, row2, dist 950 col1 = hex1$(1 TO 2) 960 row1 = hex1$(3 TO 4) 970 col2 = hex2$(1 TO 2) 980 row2 = hex2$(3 TO 4) 990 temp1 = col2 - col1 1000 temp2 = row2 - row1 1010 dist = temp1^2 + temp2^2 1020 dist = SQRT(dist) 1030 IF INT(dist) < dist THEN 1040 IF row2 = row1-1 THEN 1050 dist = INT(dist) 1060 ELSE 1070 dist = INT(dist)+1 1080 END IF 1090 END IF 1100 RETurn dist 1110 END DEFine ``` As a side note, if there are any QLer’s out there that are interested in Wargaming, I’ve got a few Freeware wargames that I have designed and a few that I have picked up off the Internet. I’ve designed one tactical space combat and one tank combat game. I have all of these as Quill documents. If any are interested, please contact me.