2014 Update:

It is now possible to write an unlimited amount of text on the mathematical surface of a magic square. Harry White made this happen. His program listed below automates the process. The 104 solutions for the letters are included in the program.

http://en.wikipedia.org/wiki/User_talk:Knecht03#mediaviewer/File:Magic_Square_Water_Retention_Surface.png

 

The graphic above is a 99 x 99 magic square depicted as a water retaining surface. If a cell is not colored in blue there is a downward path from that cell off the square.

 

This project required the following skills.

 

#1. CompleteSquare Utility - individual letters with side-specific drainage are formed on a 11 x 11 magic square. This requires 4 specific drains for each letter (up,down,right,left). The 104 solutions are contained in the code of the program below.

 

 

 

The graphics above show the template pattern that is put into the CompleteSquare utility. Note the positions of the smallest values are specified. They form the ponds and the drainage paths.

http://users.eastlink.ca/~sharrywhite/Download.html

CompleteSquare

C code

Given an input square with some cell values between 1 and n specified, (and other cell values 0), this program attempts to complete a magic square by placing the remaining values. The square type can be semimagic, magic, or associative. See notes. The output file is <N>x<N><square type>[_n].txt.

The program fills the starting square with random placement of unspecified values, and then uses "Constraint-Based Local Search" and "Tabu Search" techniques to transform the square into the indicated type. See "Water Retention on Magic Squares Solver" by Johan fverstedt.

 

 

 

 

 

#2. Composite Utility this is a construction method that replaces each cell in a base pattern magic square with what I will call a sub-square magic square. The sub-square magic square in this case is an 11 x 11 magic square with a single letter in water writing in that square. The 11 x 11 magic square has the numbers 1 to 121 in the square. The composite function increases each value in the sub-square by (n-1)*121 where n = the value in the cell in the base pattern.

 

#3. Bordered Magic Square one property of this square is that it has a configuration with zero water retention. It can be produced by a formula. Thus it is an ideal base square to use in the composite function.

 

 

*** unsolved problem all but one of the 26 letters have the 4 needed drains. The letter H is the exception. This presently requires two sides to drain out or a cheat where the H is not all connected. Truthfully I struggled to get a two sided drain done for H. All the ponds are connected. This requires every number surrounding the pond to be larger than the largest pond value. The row and col sums get to the point where they are not manageable.

This is an H that drains out both the right and left side. I feel a bit lucky to have come up with this solution.

For the graphic that started this page I used this 9 x9 magic square that had its own water retention. If letters are written on the pond areas .. they are buried underneath the water and dont show up. The TWO letters occupy the positions 75,34,54. Each cell in the 11 x 11 magic square T letter that is placed in the 75 position will be increased by 74*121 by the composite function.

http://en.wikipedia.org/wiki/User_talk:Knecht03

 

http://users.eastlink.ca/~sharrywhite/Download.html#compCalligraphy

 

/*

* File: CompositeCalligraphy.cpp

* Author: S Harry White

* Created: 2014-07-07

* Updated: 2014-08-25

*/

 

/*

* Makes a composite square of order m*n from character squares of order m and a

* square of order n. The order m magic squares show the characters as retained water.

* These squares, created by Craig Knecht, are contained in this file.

*/

 

#include "stdafx.h"

#include <conio.h>

#include <direct.h>

#include <errno.h>

#include <io.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

#include <Windows.h>

 

typedef unsigned int Uint;

int lineLength, **iSquare = NULL, **water = NULL, **oSquare = NULL,

**drainL = NULL, **drainR = NULL, **drainU = NULL, **drainD = NULL;

char *textLine = NULL; bool *numberUsed = NULL;

 

const int startSize = 25;

int allocatedSize, maxNumber;

 

struct t_Cell { int priority, row, col; };

t_Cell *Queue = NULL;

int allocatedQueueSize = 0, qIndex = 0;

//=================================== start alphabets =======================================

 

const int fontN = 11, fontNN = fontN*fontN, ASCIItableSize = 128;

typedef char t_chSquare[fontNN]; typedef char* t_drain[ASCIItableSize];

 

t_chSquare // Character squares that drain left.

spL = {

59,40,41,97,48,46,86,121,50,49,34,3,33,85,111,60,44,89,54,66,99,27,75,76,106,37,38,39,43,52,63,

116,26,83,74,79,36,61,42,64,53,56,98,25,1,4,32,35,115,112,95,117,113,23,24,84,5,6,108,55,58,73,

101,71,22,88,110,105,7,8,51,104,107,19,20,21,119,91,82,62,9,65,57,72,18,45,70,100,94,109,93,

10,11,12,13,17,78,114,120,2,47,68,102,80,67,14,103,81,30,77,69,96,92,118,87,90,15,16,28,29,31

},

n1L = {

63,93,78,75,14,15,16,110,103,39,65,116,96,113,10,13,115,17,18,37,38,98,4,6,7,8,117,43,112,19,

120,121,114,86,80,88,52,3,44,62,20,95,90,51,102,92,99,73,61,45,66,21,22,40,50,34,35,36,76,77,46,

69,107,23,101,67,84,87,53,60,71,47,56,106,24,25,58,2,79,83,64,74,48,59,97,82,26,57,94,89,91,72,

42,49,41,108,30,27,28,1,5,11,111,118,119,105,32,31,109,29,85,9,12,70,81,100,68,33,104,55,54

},

n2L = {

84,115,83,18,19,20,21,22,106,92,91,120,14,16,17,86,54,119,23,24,109,89,6,13,99,112,35,34,33,121,

25,111,82,104,117,69,1,59,79,78,26,27,55,56,3,15,97,102,94,113,110,7,28,29,73,72,108,76,70,60,9,

8,90,80,30,68,4,81,58,64,51,53,98,103,66,31,62,95,88,57,45,52,63,61,75,67,32,36,74,105,93,41,42,

43,44,40,87,65,37,2,5,12,101,77,85,50,116,114,71,38,107,10,11,100,96,118,49,48,47,46,39

},

n3L = {

101,3,4,5,118,72,43,53,85,89,98,1,2,99,60,91,77,42,76,87,102,34,93,100,75,113,10,13,14,41,115,

64,33,61,111,51,28,74,109,120,24,30,31,32,48,49,50,119,83,114,29,25,56,63,35,55,78,65,73,88,22,

21,103,59,71,36,58,68,81,106,94,23,96,26,44,38,37,66,121,79,17,70,20,108,27,57,39,67,110,116,

90,52,6,7,8,105,45,40,92,9,11,62,82,19,97,86,84,46,80,95,69,12,15,16,18,117,104,107,47,54,112

},

n4L = {

103,5,6,7,8,72,119,48,88,121,94,1,2,98,111,110,89,120,47,32,31,30,60,70,80,71,64,33,40,49,58,

117,29,50,51,52,53,34,105,41,67,74,116,28,57,69,86,35,113,59,42,82,75,26,27,85,108,97,36,37,38,

43,39,76,25,87,3,4,9,118,104,90,44,106,78,24,91,73,107,10,11,79,62,45,100,93,23,68,77,109,84,

12,13,92,46,96,21,22,99,101,81,83,115,14,15,114,19,20,54,55,61,65,66,102,95,16,17,18,56,112,63

},

n5L = {

114,3,4,120,104,48,117,29,28,27,77,1,2,76,103,86,47,69,105,95,26,61,101,84,96,39,40,41,42,43,

100,25,60,72,78,99,6,62,92,91,68,23,24,56,44,45,46,7,71,119,74,102,22,83,58,67,85,88,38,37,36,

35,93,21,108,63,5,8,9,121,79,118,112,11,20,106,82,81,90,10,18,115,64,19,12,110,98,54,107,109,

57,17,16,15,14,94,116,73,53,13,70,75,89,30,59,65,80,87,51,52,66,97,111,113,31,32,33,34,49,50,55

},

n6L = {

49,50,56,90,119,41,39,32,31,62,102,9,54,68,110,121,43,97,82,30,29,28,73,100,57,91,12,13,14,113,

67,104,27,79,69,55,33,120,84,44,20,65,76,26,37,74,61,7,98,75,95,103,72,24,25,58,66,88,38,10,36,

35,96,106,23,115,63,71,59,34,117,70,83,17,21,22,114,109,105,64,40,42,99,19,16,86,45,46,108,77,

78,111,6,15,11,51,60,107,47,1,2,81,112,18,94,118,52,53,92,48,85,3,4,5,8,101,116,89,80,87,93

},

n7L = {

86,10,11,95,47,84,99,80,54,53,52,2,5,12,66,46,109,103,113,92,81,42,119,75,101,36,35,34,33,32,

67,98,41,93,79,87,1,82,104,72,31,43,39,40,3,58,102,70,94,117,44,8,68,38,69,4,48,49,74,83,45,9,

116,110,37,96,111,85,105,51,50,6,73,78,27,28,57,29,90,61,88,76,7,77,106,26,55,56,13,14,15,114,

121,30,118,24,25,108,89,120,107,16,17,18,115,22,23,97,71,65,91,100,112,59,19,20,21,60,62,63,64

},

n8L = {

58,57,8,9,18,79,94,121,74,78,75,5,6,7,118,19,106,120,116,64,63,47,83,67,82,109,13,11,12,103,76,

69,46,107,84,102,22,95,73,23,10,66,44,45,52,114,85,21,92,80,72,20,25,29,81,97,90,62,113,17,16,

15,56,98,30,77,59,61,53,32,117,115,119,14,37,31,33,54,86,65,36,70,68,38,24,88,108,34,55,101,

104,50,28,26,27,96,60,89,35,1,2,99,110,111,48,39,40,41,87,93,100,3,4,51,91,49,112,71,42,43,105

},

n9L = {

53,54,55,58,89,44,88,67,49,51,63,2,57,56,59,96,43,108,83,48,74,45,86,80,79,90,11,15,6,110,47,

115,32,39,113,77,16,114,75,42,40,46,78,31,68,92,65,17,73,76,118,34,69,29,30,112,52,62,105,35,

36,10,38,94,28,99,8,9,37,84,120,91,106,7,97,27,85,109,60,70,20,82,93,41,33,71,26,66,98,101,102,

100,14,13,12,121,24,25,61,95,50,64,117,19,81,21,22,23,107,72,1,3,4,5,18,104,119,116,103,111,87

},

lAL = {

102,114,118,121,19,20,21,22,23,55,56,100,92,16,17,18,70,89,101,24,84,60,108,81,15,116,77,7,87,

62,25,39,54,110,13,14,74,6,106,8,112,85,40,103,4,10,41,35,69,104,94,34,93,107,80,73,88,120,29,

36,37,38,30,76,78,66,3,65,111,28,113,75,91,31,63,45,46,97,95,96,27,67,48,47,32,68,44,50,71,99,

117,26,61,49,79,33,42,43,51,2,5,12,115,119,57,58,105,82,64,52,1,9,11,83,86,98,59,109,90,72,53

},

lBL = {

1,4,5,120,79,81,85,99,59,62,76,2,11,12,118,73,83,82,101,57,64,68,95,116,114,45,6,7,8,100,53,58,

69,77,113,63,39,72,80,51,13,52,55,56,3,32,84,43,105,88,89,33,50,70,74,90,117,86,42,9,25,19,98,

49,61,75,66,112,60,41,78,54,93,34,48,47,38,10,14,110,40,109,87,91,35,71,67,37,108,15,102,44,24,

46,21,103,107,65,36,104,16,17,119,94,97,106,28,29,30,31,115,121,18,20,22,23,26,27,96,92,111

},

lCL = {

1,5,6,114,82,72,75,78,60,61,117,110,85,9,88,62,49,77,46,47,48,50,101,93,89,90,22,21,20,45,84,

55,51,3,4,107,27,104,92,106,7,95,74,52,108,102,86,26,38,37,36,44,63,65,66,119,81,71,25,76,112,

35,34,33,43,42,91,68,64,24,113,54,67,79,32,39,40,115,105,94,23,98,53,30,8,31,73,41,11,12,116,

118,19,18,17,121,87,96,56,10,13,14,120,29,80,111,109,70,58,57,2,103,15,16,28,83,97,100,69,59,99

},

lDL = {

15,9,11,112,72,74,93,95,61,77,52,2,5,12,117,49,94,109,108,60,64,51,101,84,82,46,23,22,79,88,54,

53,39,3,17,98,45,91,92,18,83,70,116,38,105,107,86,44,69,65,59,1,62,36,37,104,100,67,43,50,55,

87,16,48,35,66,102,97,85,42,57,73,63,4,56,34,58,6,7,113,41,96,99,19,114,75,33,68,119,120,90,40,

25,24,89,30,31,32,71,8,10,13,121,118,47,28,29,76,111,110,106,115,14,20,21,26,27,103,78,80,81

},

lEL = {

71,24,22,115,67,55,56,84,51,58,68,3,14,19,121,98,54,82,100,50,52,78,114,116,108,31,13,5,7,23,

49,96,109,75,110,89,30,72,92,65,33,34,35,36,1,15,32,29,74,105,106,107,95,70,37,104,117,103,28,

9,17,47,48,91,69,38,2,18,83,27,97,101,81,102,64,57,39,85,111,62,26,61,66,60,77,42,41,40,113,118,

112,25,11,6,8,10,87,88,93,4,12,20,120,90,94,86,43,63,59,80,99,16,21,119,79,76,73,44,45,46,53,

},

lFL = {

1,4,11,117,87,86,114,60,62,63,66,2,5,12,121,97,64,102,48,68,72,80,110,118,95,45,6,7,8,35,69,84,

94,3,13,107,44,90,119,103,46,33,32,81,75,82,58,43,98,65,78,54,53,31,34,106,108,71,42,9,10,92,

83,73,30,47,91,112,101,41,67,113,26,27,28,29,36,57,93,70,40,61,77,25,100,55,56,37,14,15,111,39,

115,23,24,79,104,109,38,116,16,17,120,21,22,49,88,74,89,59,96,105,18,19,20,85,50,51,52,76,99

},

lGL = {

1,4,5,111,76,77,79,103,73,83,59,2,11,12,115,69,74,82,106,72,70,58,87,108,96,88,6,7,8,90,56,68,

57,33,112,67,39,62,71,53,50,51,78,55,3,40,52,32,118,91,81,114,48,47,45,101,119,75,42,54,46,29,

9,66,86,44,97,109,64,41,61,60,102,13,49,37,38,10,15,98,43,89,99,92,14,95,36,80,117,16,84,121,

30,31,28,35,110,34,65,116,17,18,19,85,93,94,113,26,27,63,104,120,100,20,21,22,23,24,25,105,107

},

lHL = {

110,107,13,14,15,18,35,117,88,59,95,105,8,10,84,16,17,91,121,108,55,56,1,7,70,63,93,120,98,26,

82,54,57,80,102,81,64,72,97,33,30,36,37,39,4,103,100,65,101,85,50,29,47,45,42,78,104,111,66,89,

6,40,28,52,48,49,3,24,106,67,94,113,53,27,58,75,51,74,90,86,68,73,87,34,31,41,43,44,99,112,71,

69,77,23,32,25,38,79,46,2,5,11,92,21,22,109,119,60,114,116,115,9,12,19,20,83,96,118,61,62,76

},

lIL = {

100,116,110,20,21,22,23,24,72,81,82,112,74,18,19,70,114,87,25,26,60,66,119,115,17,69,7,39,6,101,

27,88,83,14,15,16,64,92,40,117,108,28,93,84,105,95,76,56,48,41,104,34,29,30,53,4,46,118,73,98,

42,47,35,99,31,78,102,77,75,57,49,43,65,54,62,32,55,3,13,111,86,85,44,113,68,79,33,36,109,106,

107,58,10,45,8,67,63,61,37,2,5,12,80,94,120,50,103,96,71,38,1,9,11,89,97,121,51,52,90,91,59

},

lJL = {

86,96,77,72,68,65,28,29,37,38,75,3,58,83,110,91,26,27,103,61,39,70,6,7,101,57,115,25,98,30,102,

40,90,120,8,55,56,106,24,95,31,93,41,42,118,23,84,107,21,22,79,32,62,80,43,117,81,60,19,20,74,

66,34,71,85,44,5,111,92,10,112,109,59,35,47,46,45,100,94,63,16,18,105,64,36,48,73,54,113,76,33,

97,14,15,4,104,49,99,67,1,108,12,13,17,119,69,116,50,78,88,2,9,11,114,89,87,82,121,51,52,53

},

lKL = {

66,9,11,109,55,57,75,82,69,68,70,2,5,12,121,53,88,73,110,111,67,29,1,119,113,48,52,114,72,37,

60,27,28,78,87,79,47,62,58,38,51,54,26,91,85,107,102,46,56,39,50,33,24,25,104,93,115,71,45,41,

40,86,34,23,59,64,35,36,49,44,61,65,63,92,22,106,98,97,100,99,43,77,76,90,18,20,21,30,3,4,120,

42,117,105,19,17,95,118,31,108,6,7,116,84,15,16,101,112,74,32,103,83,8,10,13,14,89,96,81,80,94

},

lLL = {

92,105,18,19,20,89,50,51,52,76,99,109,16,17,118,21,22,49,95,74,81,69,14,15,85,39,112,23,24,115,

106,100,38,98,88,71,40,58,67,25,84,35,68,37,120,113,101,41,60,90,26,27,28,29,36,4,104,82,42,47,

56,93,80,78,30,55,111,87,57,43,59,70,72,54,53,31,34,3,13,107,44,103,97,114,46,33,32,79,117,116,

110,45,6,7,8,10,73,96,83,2,5,12,121,94,64,108,48,77,65,75,1,9,11,119,91,86,102,61,62,63,66

},

lML = {

1,5,8,111,62,86,61,118,60,68,91,2,100,9,117,55,78,53,116,51,50,40,24,105,93,47,54,90,52,31,87,

49,39,110,104,89,46,3,108,4,30,74,65,38,92,97,83,45,80,22,94,29,58,35,36,103,113,101,44,88,23,

67,28,33,34,37,6,7,48,43,114,109,99,27,66,71,81,107,10,96,42,98,21,32,26,70,84,85,112,11,115,

41,82,20,69,25,56,64,76,102,13,14,119,18,19,63,121,57,72,73,12,106,15,16,17,95,77,120,59,79,75

},

lNL = {

4,5,7,9,17,117,112,121,114,111,54,106,98,8,80,18,21,52,116,47,79,46,102,87,81,63,99,22,62,26,

42,43,44,93,86,82,64,3,104,51,30,55,50,53,24,109,83,65,103,2,96,29,74,38,48,84,77,92,66,85,57,

1,28,71,37,73,32,39,94,67,108,110,45,27,41,36,72,97,56,78,68,88,95,40,31,34,35,49,10,11,119,69,

115,23,33,25,58,107,101,113,12,13,105,19,20,89,120,59,60,61,6,91,14,15,16,100,90,118,76,75,70

},

lOL = {

101,53,15,16,17,52,76,87,49,116,89,10,13,14,64,21,102,119,106,48,94,80,120,104,67,98,18,19,20,

27,47,108,43,121,93,95,41,45,55,78,22,46,33,42,4,86,103,40,69,68,81,23,83,32,82,107,62,61,39,

75,77,74,24,58,31,63,3,71,73,38,113,100,70,25,57,30,91,85,79,115,37,109,65,44,26,28,29,54,117,

96,105,90,6,7,8,114,59,34,35,2,5,11,97,88,60,50,118,112,92,36,1,9,12,111,110,66,51,99,84,72,56

},

lPL = {

1,4,11,118,79,87,102,91,56,58,64,2,5,12,119,78,98,86,89,55,62,65,116,111,117,45,6,7,8,53,54,71,

83,3,13,47,44,88,101,112,35,66,68,94,93,61,74,43,95,81,77,10,57,32,48,113,109,90,42,9,31,46,75,

59,30,67,72,107,84,41,73,82,92,27,28,29,36,34,120,97,40,103,33,25,26,76,80,37,14,15,104,39,99,

23,24,114,105,96,38,108,16,17,121,21,22,49,100,63,85,69,115,110,18,19,20,106,50,51,52,60,70

},

lQL = {

23,51,57,58,65,69,50,90,49,82,77,116,95,75,89,72,61,22,24,25,26,66,97,94,67,111,6,7,8,120,68,

37,56,113,100,64,15,21,71,45,36,81,38,87,4,10,107,16,52,84,118,35,104,39,102,117,14,20,17,88,

119,101,34,80,40,41,99,112,62,18,91,13,85,33,53,63,42,3,108,86,19,74,103,27,32,70,106,43,96,73,

110,105,28,29,30,31,46,79,44,1,5,11,109,98,55,92,121,47,78,54,2,9,12,114,76,60,93,115,48,83,59

},

lRL = {

1,4,5,119,86,74,76,100,54,69,83,2,11,12,118,85,52,81,104,53,88,65,109,121,117,45,6,7,8,48,51,

96,63,75,113,66,39,78,84,72,13,47,46,38,3,32,90,43,108,92,99,33,57,77,37,97,114,89,42,9,25,19,

102,70,68,36,71,116,60,41,64,62,101,26,61,34,35,10,14,103,40,105,112,106,27,30,31,93,95,15,94,

44,87,73,29,28,107,49,50,110,16,17,120,22,23,24,111,82,55,91,98,115,18,20,21,67,56,79,59,58,80

},

lSL = {

6,7,9,13,73,105,95,107,50,115,91,72,100,66,14,59,54,70,84,49,51,52,111,113,116,17,12,11,10,18,

48,121,94,99,96,101,16,60,71,103,8,19,20,78,27,81,82,15,79,56,106,97,85,21,22,57,65,63,92,41,

42,40,67,69,112,23,34,46,47,108,76,58,44,36,80,118,24,83,89,102,53,61,62,90,37,43,26,25,64,68,

77,104,38,39,35,75,88,28,55,1,2,3,119,74,86,45,110,109,29,93,117,4,5,120,98,87,33,32,31,30,114

},

lTL = {

61,63,53,54,56,80,59,84,65,62,34,2,4,17,106,90,115,55,116,73,60,33,118,110,109,35,3,51,38,5,67,

103,32,6,7,18,83,102,50,77,112,93,92,31,74,69,100,68,58,49,57,101,36,29,30,89,64,111,79,71,48,

52,43,42,28,44,8,9,10,119,66,47,72,120,98,27,95,114,104,11,85,88,46,70,24,25,26,78,107,105,12,

13,81,45,75,23,37,86,87,1,39,113,14,40,121,96,22,41,76,108,91,97,117,15,16,19,20,21,94,82,99

},

lUL = {

79,9,11,109,57,45,59,119,50,60,73,2,5,12,117,100,44,107,120,49,83,32,111,112,40,34,76,43,86,18,

48,72,31,113,116,93,39,41,42,84,22,33,58,30,1,110,114,36,77,102,71,21,29,82,28,90,87,106,37,67,

108,78,20,25,26,27,3,7,105,38,75,88,61,19,104,74,97,101,96,69,35,66,63,24,23,51,52,91,80,62,92,

95,6,4,8,121,85,53,65,81,54,15,16,17,68,46,118,103,55,98,10,13,14,115,89,64,47,70,94,56,99

},

lVL = {

1,5,11,120,118,109,44,45,46,105,67,2,9,12,102,83,68,43,117,114,55,66,103,94,95,34,48,47,42,35,

71,49,53,3,97,80,30,79,65,85,27,107,41,57,104,78,72,31,74,54,50,26,86,40,56,4,101,90,32,70,61,

82,25,108,39,59,110,84,76,33,58,64,96,24,37,38,51,6,7,112,89,29,98,28,121,36,93,52,113,8,10,87,

81,19,91,116,23,63,60,119,77,13,14,15,69,92,115,22,73,62,106,111,100,99,16,17,18,20,21,75,88

},

lWL = {

12,106,15,16,17,95,77,120,59,79,75,102,13,14,119,18,19,63,121,57,72,73,112,11,115,41,82,20,69,

25,56,64,76,107,10,96,42,98,21,32,26,70,84,85,6,7,48,43,114,109,99,27,66,71,81,103,113,101,44,

88,23,67,28,33,34,37,92,97,83,45,80,22,94,29,58,35,36,110,104,89,46,3,108,4,30,74,65,38,24,105,

93,47,54,90,52,31,87,49,39,2,100,9,117,55,78,53,116,51,50,40,1,5,8,111,62,86,61,118,60,68,91

},

lXL = {

62,102,93,85,82,57,18,19,20,21,112,64,111,88,105,15,16,17,103,63,22,67,69,109,74,10,14,68,96,

32,110,23,66,70,118,13,8,117,84,108,31,73,24,25,100,6,7,51,47,52,46,120,97,119,26,3,4,76,95,92,

50,86,94,58,80,33,38,99,89,72,49,60,48,78,43,61,34,65,106,87,27,81,77,90,30,37,36,35,1,2,121,

28,53,107,39,29,71,116,104,101,5,11,115,42,41,40,44,45,114,113,98,9,12,75,79,59,83,91,54,55,56

},

lYL = {

116,5,11,84,53,54,64,91,80,57,56,1,2,9,99,46,110,76,121,102,67,38,90,96,44,29,45,94,63,31,82,

60,37,77,78,95,28,87,68,59,30,58,55,36,86,66,101,93,26,88,27,112,23,24,25,3,47,48,100,43,32,74,

118,22,71,113,83,72,49,50,65,33,70,98,21,61,69,4,106,111,104,105,34,89,19,20,39,40,85,75,81,62,

73,35,42,18,108,51,41,6,7,8,10,115,109,92,17,103,107,97,120,117,114,12,13,14,15,16,52,79,119

},

lZL = {

70,5,6,77,73,81,68,110,58,59,64,1,2,88,104,60,109,67,39,51,79,71,108,118,103,8,20,21,22,23,111,

94,43,3,7,98,113,92,112,99,24,40,41,42,86,120,87,15,16,19,17,25,90,95,101,100,116,13,14,97,18,

84,26,27,74,102,119,11,12,117,52,54,69,105,28,29,75,9,10,38,36,106,121,89,115,80,30,37,93,114,

107,35,34,33,32,31,72,76,44,4,85,62,96,66,50,61,91,65,46,45,78,83,57,56,55,53,63,82,49,48,47

};

 

t_drain leftC = { // ASCII table of pointers to left draining character squares.

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

spL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// sp ! " # $ % & ' ( ) * + , - . /

lOL, n1L, n2L, n3L, n4L, n5L, n6L, n7L, n8L, n9L, NULL,NULL,NULL,NULL,NULL,NULL,

// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

NULL,lAL, lBL, lCL, lDL, lEL, lFL, lGL, lHL, lIL, lJL, lKL, lLL, lML, lNL, lOL,

// @ A B C D E F G H I J K L M N O

lPL, lQL, lRL, lSL, lTL, lUL, lVL, lWL, lXL, lYL, lZL, NULL,NULL,NULL,NULL,NULL,

// P Q R S T U V W X Y Z [ \ ] ^ _

NULL,lAL, lBL, lCL, lDL, lEL, lFL, lGL, lHL, lIL, lJL, lKL, lLL, lML, lNL, lOL,

// ` a b c d e f g h i j k l m n o

lPL, lQL, lRL, lSL, lTL, lUL, lVL, lWL, lXL, lYL, lZL, NULL,NULL,NULL,NULL,NULL

// p q r s t u v w x y z { | } ~ DEL

};

 

t_chSquare // Character squares that drain right.

spR = {

31,29,28,16,15,90,87,118,92,96,69,77,30,81,103,14,67,80,102,68,47,2,120,114,78,17,13,12,11,10,

93,109,94,100,70,45,18,72,57,65,9,62,82,91,119,21,20,19,107,104,51,8,7,105,110,88,22,71,101,73,

58,55,108,6,5,84,24,23,113,117,95,112,115,35,32,4,1,25,98,56,53,64,42,61,36,79,74,83,26,116,

63,52,43,39,38,37,106,76,75,27,99,66,54,89,44,60,111,85,33,3,34,49,50,121,86,46,48,97,41,40,59

},

n1R = {

67,66,65,17,16,15,14,81,114,103,113,68,104,108,18,71,110,13,10,8,60,101,120,121,20,19,115,43,

98,118,7,6,4,54,77,21,50,3,44,58,89,88,85,102,53,23,22,105,70,45,57,34,95,87,80,90,24,116,109,

73,46,91,32,31,30,29,26,25,72,52,51,47,76,33,94,96,99,27,63,92,59,75,48,55,38,100,112,2,28,35,

79,83,42,49,41,69,111,78,56,64,36,37,119,93,117,82,106,11,5,1,74,97,39,40,62,107,86,61,12,9,84

},

n2R = {

94,77,99,20,19,18,17,16,93,114,104,76,47,22,21,108,106,49,15,14,121,92,80,118,23,117,35,34,33,

120,13,10,88,79,113,24,1,98,107,101,26,115,4,3,57,27,25,75,91,66,85,7,86,90,62,69,28,50,51,53,

6,8,103,102,119,82,30,29,72,110,52,71,111,73,46,39,38,31,64,63,45,54,56,55,96,65,84,58,32,83,

95,41,42,43,44,40,116,74,61,36,37,109,112,59,97,100,105,9,5,2,87,48,89,78,60,67,68,70,12,11,81

},

n3R = {

73,68,55,45,46,47,116,102,54,3,62,34,100,53,44,87,63,119,109,59,2,1,33,97,70,43,10,13,14,107,

82,121,81,32,31,88,28,76,98,42,24,64,113,75,95,30,83,57,78,66,120,25,40,39,38,72,29,56,108,79,

23,22,41,84,99,58,106,21,20,19,94,77,85,26,65,69,89,36,35,52,17,18,112,114,27,67,101,92,37,96,

93,103,6,7,8,80,71,110,60,48,49,50,117,86,104,16,118,74,5,4,105,115,51,90,91,61,15,12,11,9,111

},

n4R = {

82,74,31,32,47,66,121,72,78,5,63,27,68,30,97,103,76,120,58,89,2,1,26,28,29,111,56,33,40,57,81,

116,94,25,102,115,67,34,73,41,55,54,53,52,24,23,109,35,65,70,42,71,77,91,64,105,22,118,36,37,

38,43,39,85,79,69,59,21,20,106,98,107,44,110,99,4,3,60,112,19,18,113,95,45,100,7,6,96,61,80,101,

17,16,86,46,88,8,93,75,119,90,49,48,15,14,117,10,9,108,92,83,51,50,104,87,13,12,11,84,114,62

},

n5R = {

94,109,87,117,31,30,29,5,4,90,75,28,81,70,114,110,99,111,52,3,2,1,27,106,62,39,40,41,42,43,78,

77,116,26,55,53,6,56,65,73,105,84,66,82,25,24,69,7,71,80,96,113,112,64,10,59,23,61,38,37,36,

35,121,98,91,72,101,22,102,119,68,100,118,11,13,9,8,92,21,20,19,115,104,18,12,108,79,83,85,93,

48,17,16,15,14,120,63,103,97,76,86,49,107,67,54,89,44,34,33,32,58,51,50,88,60,47,46,45,74,57,95

},

n6R = {

87,111,103,116,119,104,18,5,4,3,1,72,107,23,22,21,81,19,117,64,50,95,61,25,24,121,12,13,14,100,

102,101,98,66,26,71,33,41,93,82,20,70,60,109,85,27,97,7,106,91,120,84,37,9,8,99,28,94,38,10,

36,35,105,62,52,112,30,29,69,34,118,76,73,17,65,92,68,31,78,46,40,42,75,114,16,77,113,39,32,115,

47,110,6,15,11,90,79,80,86,45,74,48,83,108,43,96,59,56,57,2,63,51,49,67,88,44,89,58,55,54,53

},

n7R = {

80,92,49,48,89,119,78,53,5,4,54,40,74,117,47,60,116,95,107,10,3,2,39,71,111,36,35,34,33,32,108,

105,67,38,37,83,1,58,100,63,31,120,84,56,70,30,86,81,59,68,46,8,104,62,57,90,29,106,109,76,45,

9,96,88,12,11,69,28,27,121,103,6,91,97,14,13,102,87,101,26,112,82,7,18,16,15,113,94,51,50,21,

20,19,17,75,110,79,115,114,52,93,22,72,65,98,99,44,43,42,41,55,66,23,24,25,61,64,77,85,118,73

},

n8R = {

105,43,42,71,112,49,91,51,4,3,100,93,87,41,40,39,48,111,110,99,2,1,35,89,60,96,27,26,28,50,104,

101,55,34,108,88,24,38,68,70,36,65,86,54,33,31,37,14,119,115,117,32,53,61,59,77,30,98,56,15,

16,17,113,62,90,97,81,29,25,20,72,80,92,21,85,114,52,45,44,66,10,23,73,95,22,102,84,107,46,69,

76,103,12,11,13,109,82,67,83,47,63,64,116,120,106,19,118,7,6,5,75,78,74,121,94,79,18,9,8,57,58

},

n9R = {

93,87,80,89,116,101,8,5,4,3,85,48,92,53,52,118,94,18,112,81,2,1,47,107,60,51,11,15,6,111,78,

77,108,46,45,86,16,19,99,42,40,64,105,109,114,22,21,17,83,70,117,34,59,71,63,115,23,106,96,35,

36,10,38,88,66,58,25,24,72,103,95,75,98,7,61,74,37,26,76,65,20,44,84,120,33,55,69,79,27,104,67,

113,14,13,12,91,57,100,73,28,29,30,82,97,43,121,110,68,54,9,102,62,31,32,39,41,119,90,56,50,49

},

lAR = {

56,55,23,22,21,20,19,121,118,114,102,60,84,24,101,89,70,18,17,16,92,100,54,39,25,62,87,7,77,

116,15,81,108,103,40,85,112,8,106,6,74,14,13,110,80,107,93,34,94,104,69,35,41,10,4,66,78,76,30,

38,37,36,29,120,88,73,46,45,63,31,91,75,113,28,111,65,3,50,44,68,32,47,48,67,27,96,95,97,51,43,

42,33,79,49,61,26,117,99,71,52,64,82,105,58,57,119,115,12,5,2,53,72,90,109,59,98,86,83,11,9,1

},

lBR = {

67,55,56,111,91,83,85,113,5,4,1,75,53,65,118,73,72,93,97,12,11,2,68,52,77,45,6,7,8,98,107,115,

88,76,51,50,39,61,79,49,13,59,116,78,66,62,60,43,99,86,117,33,70,32,3,63,71,69,42,9,25,19,106,

64,119,84,38,47,48,41,105,58,54,34,57,109,80,37,89,81,40,82,92,101,35,90,14,10,36,74,108,44,24,

46,21,104,96,15,103,31,30,29,121,95,100,102,18,17,16,112,114,87,28,27,26,23,22,20,94,120,110

},

lCR = {

95,76,64,96,40,39,84,91,75,6,5,47,120,63,109,74,38,89,11,10,9,101,46,56,60,61,22,21,20,62,119,

92,112,45,35,58,27,32,80,98,7,71,113,105,59,34,33,26,117,88,116,100,73,13,12,66,86,114,25,82,

121,28,16,15,14,104,55,37,36,24,108,72,29,81,69,111,49,68,87,41,23,31,93,30,8,78,115,97,65,43,

42,102,19,18,17,107,90,85,83,48,44,106,99,94,50,103,118,4,3,2,77,53,54,79,52,51,57,70,67,110,1

},

lDR = {

65,100,63,117,75,56,95,15,12,11,62,53,52,51,106,60,55,105,97,81,9,2,74,90,49,40,1,22,82,110,94,

104,5,38,115,69,43,98,89,18,73,108,17,3,37,39,47,44,57,85,71,23,114,61,93,36,77,67,45,50,54,

80,16,76,83,87,35,34,64,42,78,88,58,4,48,121,99,111,33,116,41,109,101,19,120,8,7,6,59,32,86,46,

24,25,102,103,10,66,118,91,31,30,119,92,70,20,14,13,79,112,72,68,29,28,27,26,21,96,107,113,84

},

lER = {

47,64,65,119,74,56,54,46,22,24,100,42,93,66,121,96,89,95,33,19,14,3,41,113,97,31,13,5,7,23,107,

120,114,40,35,34,25,94,84,82,77,79,115,6,91,36,72,29,49,104,80,92,102,15,1,48,37,63,28,2,17,68,

98,87,112,111,83,38,71,27,81,90,78,103,73,18,9,45,39,43,26,67,50,62,60,61,110,108,105,101,52,

30,20,32,8,10,88,116,109,70,58,53,118,99,75,86,85,12,11,4,59,57,55,117,76,69,51,44,21,16,106

},

lFR = {

84,67,64,118,54,53,52,83,38,55,3,88,58,59,120,69,51,50,101,37,36,2,65,57,86,45,32,34,33,35,76,

105,103,100,56,61,44,91,95,89,117,7,6,5,29,30,48,43,107,87,72,10,8,116,121,28,110,81,42,9,31,

90,11,94,66,109,27,113,62,41,114,77,97,12,78,46,4,26,25,82,40,98,99,14,13,112,47,115,79,24,85,

39,60,16,15,92,80,75,106,71,23,22,119,18,17,63,93,73,70,102,74,108,21,20,19,111,96,104,68,49,1

},

lGR = {

101,106,98,121,97,105,15,12,10,5,1,67,103,21,20,19,76,16,92,59,85,113,52,23,22,117,6,7,8,115,

91,120,110,94,24,58,39,48,66,89,50,64,77,62,102,25,88,32,119,78,82,107,18,17,3,68,26,84,42,100,

46,29,9,44,111,112,33,27,74,41,81,70,118,13,65,80,69,34,109,56,43,71,60,104,14,93,47,40,37,79,

61,73,30,31,28,35,96,114,87,38,86,54,53,49,57,99,116,36,11,72,45,63,55,90,51,75,83,108,95,4,2

},

lHR = {

76,62,61,118,96,83,20,19,12,9,115,116,114,60,119,109,22,21,92,11,5,2,46,79,38,25,32,23,77,69,

71,112,99,44,43,41,31,34,87,73,68,86,90,74,51,75,58,27,53,113,94,67,106,24,3,49,48,52,28,40,6,

89,66,111,104,78,42,45,47,29,50,85,101,65,100,103,4,39,37,36,30,33,97,72,64,81,102,80,57,54,82,

26,98,120,93,63,70,7,1,56,55,108,121,91,17,16,84,10,8,105,95,59,88,117,35,18,15,14,13,107,110

},

lIR = {

82,81,72,24,23,22,21,20,110,116,100,66,60,26,25,87,114,70,19,18,74,112,83,88,27,101,6,39,7,69,

17,115,119,84,93,28,108,117,40,92,64,16,15,14,53,30,29,34,104,41,48,56,76,95,105,78,31,99,35,

47,42,98,73,118,46,4,55,32,62,54,65,43,49,57,75,77,102,36,33,79,68,113,44,85,86,111,13,3,37,61,

63,67,8,45,10,58,107,106,109,38,71,96,103,50,120,94,80,12,5,2,59,91,90,52,51,121,97,89,11,9,1

},

lJR = {

76,89,77,94,64,63,71,120,11,5,1,27,84,74,90,113,62,80,118,12,9,2,26,85,53,82,38,46,47,30,91,73,

100,25,92,52,72,37,49,83,31,86,111,33,24,67,39,28,29,50,96,32,98,105,103,23,22,21,20,106,104,

61,34,102,109,69,75,42,41,18,97,60,59,35,78,87,79,119,43,101,17,19,107,112,36,110,4,3,117,44,

114,115,8,7,6,121,13,10,116,93,45,48,81,95,68,16,15,14,88,108,66,58,51,54,65,55,40,99,56,70,57

},

lKR = {

115,113,82,120,91,106,16,10,8,7,3,67,87,51,116,19,18,17,90,50,76,80,46,35,48,26,32,57,107,60,

62,103,95,52,34,33,30,54,74,22,108,63,105,96,37,36,45,29,104,4,88,92,64,101,71,38,53,49,28,24,

23,77,111,78,109,81,39,86,85,27,59,102,15,117,79,41,21,40,42,56,31,55,72,100,14,58,110,93,75,43,

83,25,99,84,112,13,114,12,11,68,44,66,118,69,70,97,47,89,2,1,94,98,73,121,65,61,20,9,6,5,119

},

lLR = {

72,96,28,27,26,101,102,87,66,56,10,60,30,29,117,25,24,85,80,95,113,13,35,31,81,39,68,23,22,63,

112,86,111,36,74,94,40,84,93,21,33,70,71,55,37,38,46,41,92,32,20,88,82,76,119,50,64,91,42,75,

34,19,18,78,79,121,51,52,57,43,105,59,97,17,16,58,116,62,69,77,44,83,100,98,106,15,14,3,99,107,

47,45,6,7,8,9,114,109,120,65,49,48,118,53,108,110,103,11,4,2,104,61,73,115,54,90,89,67,12,5,1

},

lMR = {

91,68,60,118,61,86,62,111,8,5,1,40,50,51,116,53,78,55,117,9,100,2,39,49,87,31,52,90,54,47,93,

105,24,38,65,74,30,4,108,3,46,89,104,110,36,35,58,29,94,22,80,45,83,97,92,37,34,33,28,67,23,88,

44,101,113,103,81,71,66,27,99,109,114,43,48,7,6,85,84,70,26,32,21,98,42,96,10,107,76,64,56,25,

69,20,82,41,115,11,112,73,72,57,121,63,19,18,119,14,13,102,75,79,59,120,77,95,17,16,15,106,12

},

lNR = {

73,111,108,121,100,116,17,9,7,5,4,57,72,53,120,90,21,18,71,8,55,106,44,43,42,31,47,22,107,63,

81,95,96,45,49,46,30,3,101,86,64,82,88,77,75,38,94,29,70,2,89,65,83,102,24,52,37,51,28,54,98,

1,66,92,87,105,48,36,41,27,74,113,91,67,103,39,32,50,35,34,26,40,56,110,68,79,80,93,104,112,58,

25,33,23,117,69,109,11,10,61,60,59,119,76,20,19,114,13,12,118,62,78,85,115,84,99,16,15,14,97,6

},

lOR = {

89,116,49,87,76,52,17,16,15,53,101,80,94,48,106,119,102,21,64,14,13,10,43,108,47,27,20,19,18,98,

67,104,120,42,33,46,22,78,55,45,41,95,93,121,82,32,83,23,81,68,69,40,103,86,4,63,31,58,24,74,

77,75,39,61,62,107,91,30,57,25,70,100,113,38,73,71,3,54,29,28,26,44,65,109,37,115,79,85,35,34,

59,114,8,7,6,90,105,96,117,36,92,112,118,50,60,88,97,11,5,2,56,72,84,99,51,66,110,111,12,9,1

},

lPR = {

53,84,50,115,70,66,65,64,11,4,89,37,48,49,120,106,99,92,103,12,3,2,36,118,96,45,6,7,8,121,116,

117,1,34,97,51,44,69,77,59,35,54,56,95,33,94,55,43,68,76,79,10,87,88,38,32,30,104,42,9,31,46,

47,111,110,109,112,29,108,41,114,113,107,15,14,13,5,100,28,52,40,101,80,17,16,58,86,93,75,27,

57,39,85,19,18,102,73,71,105,78,26,25,119,21,20,98,91,72,61,60,81,90,24,23,22,83,82,67,63,62,74

},

lQR = {

100,110,65,101,120,23,22,21,20,14,75,58,55,60,78,93,24,103,98,88,10,4,57,44,52,68,6,7,8,119,86,

111,113,95,43,53,15,25,96,70,36,80,102,56,38,37,26,16,116,99,83,35,48,84,89,39,72,59,17,74,97,

109,34,76,91,3,40,87,54,18,71,13,81,33,67,92,115,41,73,69,19,45,104,27,32,66,90,105,42,49,62,

112,28,29,30,31,117,63,108,79,50,107,106,46,85,61,118,12,5,2,82,51,64,121,47,94,77,114,11,9,1

},

lRR = {

70,53,52,116,104,73,94,102,4,2,1,57,56,51,80,58,60,62,86,11,63,87,68,71,50,37,6,7,8,113,103,

109,99,95,40,39,36,78,115,77,19,84,83,5,42,41,49,35,88,67,117,25,85,110,12,43,69,61,34,9,33,13,

118,93,90,108,44,81,59,32,105,66,92,26,91,72,3,45,111,74,31,82,100,101,27,76,14,10,46,47,96,30,

38,98,64,28,89,15,120,106,48,75,121,24,23,22,107,17,16,112,55,54,65,119,79,29,21,20,18,97,114

},

lSR = {

31,29,28,16,15,78,97,113,108,99,57,85,30,71,102,14,65,75,120,56,51,2,112,110,94,19,12,11,10,13,

84,105,101,90,86,74,17,69,66,68,8,43,83,67,111,21,20,18,119,82,81,9,7,100,103,106,22,80,115,41,

42,40,116,6,5,98,24,23,32,121,107,96,109,36,118,4,1,25,93,63,52,92,55,61,37,62,58,73,26,117,

64,53,38,39,35,59,72,89,79,27,91,95,54,76,60,48,114,70,33,3,34,49,50,104,88,77,47,46,45,44,87

},

lTR = {

34,62,65,84,59,80,56,54,53,63,61,33,60,73,116,55,115,90,106,17,4,2,32,103,67,5,38,51,3,35,109,

110,118,31,92,93,112,77,50,102,83,18,7,6,30,29,36,101,57,49,58,68,100,69,74,44,28,42,43,52,48,

71,79,111,64,89,95,27,98,120,72,47,66,119,10,9,8,78,26,25,24,70,46,88,85,11,104,114,87,86,37,

23,75,45,81,13,12,105,107,108,76,41,22,96,121,40,14,113,39,1,99,82,94,21,20,19,16,15,117,97,91

},

lUR = {

73,60,50,119,59,45,57,109,11,9,79,32,83,49,120,107,44,100,117,12,5,2,31,72,48,18,86,43,76,34,

40,112,111,30,58,33,22,84,42,41,39,93,116,113,28,82,29,21,71,102,77,36,114,110,1,27,26,25,20,78,

108,67,37,106,87,90,97,74,104,19,61,88,75,38,105,7,3,91,52,51,23,24,63,66,35,69,96,101,65,53,

85,121,8,4,6,95,92,62,80,98,55,103,118,46,68,17,16,15,54,81,99,56,94,70,47,64,89,115,14,13,10

},

lVR = {

67,105,46,45,44,109,118,120,11,5,1,66,55,114,117,43,68,83,102,12,9,2,53,49,71,35,42,47,48,34,

95,94,103,57,41,107,27,85,65,79,30,80,97,3,56,40,86,26,50,54,74,31,72,78,104,59,39,108,25,82,

61,70,32,90,101,4,51,38,37,24,96,64,58,33,76,84,110,52,93,36,121,28,98,29,89,112,7,6,60,63,23,

116,91,19,81,87,10,8,113,62,73,22,115,92,69,15,14,13,77,119,88,75,21,20,18,17,16,99,100,111,106

},

lWR = {

75,79,59,120,77,95,17,16,15,106,12,73,72,57,121,63,19,18,119,14,13,102,76,64,56,25,69,20,82,41,

115,11,112,85,84,70,26,32,21,98,42,96,10,107,81,71,66,27,99,109,114,43,48,7,6,37,34,33,28,67,

23,88,44,101,113,103,36,35,58,29,94,22,80,45,83,97,92,38,65,74,30,4,108,3,46,89,104,110,39,49,

87,31,52,90,54,47,93,105,24,40,50,51,116,53,78,55,117,9,100,2,91,68,60,118,61,86,62,111,8,5,1

},

lXR = {

112,21,20,19,18,57,82,85,93,102,62,67,22,63,103,17,16,15,105,88,111,64,66,23,110,32,96,68,14,

10,74,109,69,25,24,73,31,108,84,117,8,13,118,70,26,119,97,120,46,52,47,51,7,6,100,33,80,58,94,

86,50,92,95,76,4,3,34,61,43,78,48,60,49,72,89,99,38,35,36,37,30,90,77,81,27,87,106,65,104,116,

71,29,39,107,53,28,121,2,1,113,114,45,44,40,41,42,115,11,5,101,56,55,54,91,83,59,79,75,12,9,98

},

lYR = {

56,57,80,91,64,54,53,84,11,5,116,38,67,102,121,76,110,46,99,9,2,1,37,60,82,31,63,94,45,29,44,

96,90,36,55,58,30,59,68,87,28,95,78,77,25,24,23,112,27,88,26,93,101,66,86,113,71,22,118,74,32,

43,100,48,47,3,69,61,21,98,70,33,65,50,49,72,83,40,39,20,19,89,34,105,104,111,106,4,41,51,108,

18,42,35,73,62,81,75,85,97,107,103,17,92,109,115,10,8,7,6,119,79,52,16,15,14,13,12,114,117,120

},

lZR = {

47,48,49,82,63,53,55,56,57,83,78,45,46,65,91,61,50,66,96,62,85,4,44,76,72,31,32,33,34,35,107,

114,93,37,30,80,115,89,121,106,36,38,10,9,75,29,28,105,69,54,52,117,12,11,119,102,74,27,26,84,

18,97,14,13,116,100,101,95,90,25,17,19,16,15,87,120,86,42,41,40,24,99,112,92,113,98,7,3,43,94,

111,23,22,21,20,8,103,118,108,71,79,51,39,67,109,60,104,88,2,1,64,59,58,110,68,81,73,77,6,5,70

};

 

t_drain rightC = { // ASCII table of pointers to right draining character squares.

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

spR, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// sp ! " # $ % & ' ( ) * + , - . /

lOR, n1R, n2R, n3R, n4R, n5R, n6R, n7R, n8R, n9R, NULL,NULL,NULL,NULL,NULL,NULL,

// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

NULL,lAR, lBR, lCR, lDR, lER, lFR, lGR, lHR, lIR, lJR, lKR, lLR, lMR, lNR, lOR,

// @ A B C D E F G H I J K L M N O

lPR, lQR, lRR, lSR, lTR, lUR, lVR, lWR, lXR, lYR, lZR, NULL,NULL,NULL,NULL,NULL,

// P Q R S T U V W X Y Z [ \ ] ^ _

NULL,lAR, lBR, lCR, lDR, lER, lFR, lGR, lHR, lIR, lJR, lKR, lLR, lMR, lNR, lOR,

// ` a b c d e f g h i j k l m n o

lPR, lQR, lRR, lSR, lTR, lUR, lVR, lWR, lXR, lYR, lZR, NULL,NULL,NULL,NULL,NULL

// p q r s t u v w x y z { | } ~ DEL

};

 

t_chSquare // Character squares that drain up.

spU = {

69,2,94,91,110,84,1,83,75,3,59,96,47,109,82,105,5,4,74,76,33,40,92,68,93,62,7,6,32,79,106,85,

41,118,102,10,9,8,108,35,36,37,111,97,87,80,11,65,51,55,115,61,38,60,48,90,67,12,57,104,58,112,

42,39,44,46,15,14,13,72,107,73,95,64,43,89,86,16,103,17,18,19,101,117,53,52,54,121,28,81,78,45,

20,71,113,56,63,66,50,29,30,114,70,21,22,23,98,116,99,49,31,77,120,100,119,88,24,25,26,27,34

},

n1U = {

4,109,67,1,94,118,81,2,73,114,8,5,59,89,24,71,120,68,39,96,91,9,6,50,100,86,104,33,41,40,82,

119,10,7,113,99,80,3,32,105,97,112,12,11,15,16,101,111,69,31,42,107,63,13,103,116,17,18,55,87,

30,79,64,85,14,106,117,72,19,88,75,29,77,43,21,20,110,95,60,23,54,53,28,78,76,22,90,92,115,61,

57,70,26,27,25,93,34,65,98,108,52,51,56,44,102,37,36,35,84,66,83,62,47,46,45,121,38,74,48,49,58

},

n2U = {

66,95,2,102,111,28,20,21,6,121,99,98,81,3,15,19,110,109,114,7,8,107,82,85,92,91,16,17,18,100,

101,9,60,77,90,23,1,22,106,105,45,104,10,88,58,25,24,97,83,96,108,46,47,11,76,103,26,118,113,

117,4,5,48,112,12,13,57,29,93,72,42,49,64,59,73,119,14,31,30,41,40,84,87,80,70,65,116,27,32,79,

115,35,36,37,38,39,62,120,78,33,75,71,52,74,69,61,43,44,94,55,34,56,89,53,67,68,63,86,50,51,54

},

n3U = {

110,91,2,81,85,77,72,111,3,1,38,70,5,4,88,87,76,63,119,57,50,52,109,9,99,49,6,7,8,120,78,83,103,

11,10,121,29,62,112,48,27,97,61,93,15,69,68,65,92,80,106,26,53,60,37,16,82,86,89,98,18,19,47,

75,105,36,17,20,21,25,96,108,116,22,107,104,35,74,95,73,24,28,101,115,23,71,33,34,114,118,100,

113,12,13,14,30,31,32,94,56,55,51,66,64,39,67,102,54,58,59,79,117,46,42,41,40,43,44,45,84,90

},

n4U = {

7,117,116,98,8,80,113,21,20,1,90,97,110,108,10,9,75,114,76,67,2,3,102,104,12,11,107,28,37,83,

68,115,4,120,14,13,121,29,118,32,101,112,6,5,87,15,94,30,85,61,38,52,53,77,79,105,16,111,34,33,

39,41,31,72,96,93,22,17,18,106,91,74,40,57,71,86,89,23,82,19,73,99,56,36,55,62,88,78,24,100,

84,81,103,45,35,46,47,48,58,25,26,27,42,43,44,119,95,49,92,109,59,70,69,65,64,51,66,54,50,60,63

},

n5U = {

56,1,31,118,95,33,78,81,90,4,84,3,2,76,116,87,44,92,57,91,5,98,86,111,103,43,6,37,42,41,82,8,

112,47,46,45,40,102,101,94,83,15,9,89,48,77,54,7,85,80,73,58,18,96,75,79,107,72,38,10,36,35,109,

19,114,52,71,30,74,117,88,100,105,17,20,24,25,59,29,23,22,120,121,21,16,115,119,26,93,108,70,

11,12,13,14,106,104,113,27,64,63,62,99,32,67,68,53,66,69,28,65,97,61,60,34,39,49,50,51,110,55

},

n6U = {

92,1,37,79,102,18,120,77,82,9,54,3,2,61,110,112,19,121,80,67,41,55,4,98,66,117,12,13,14,90,95,

78,84,5,96,105,33,118,104,21,20,22,56,91,8,63,85,7,62,88,113,97,23,52,73,106,99,89,38,10,36,35,

51,24,107,76,109,75,53,34,94,74,119,17,25,32,39,83,59,65,40,100,101,26,16,81,58,42,103,50,49,

115,6,15,11,108,111,60,43,86,57,31,69,27,87,45,68,93,64,44,72,71,30,29,28,116,46,47,48,114,70

},

n7U = {

89,1,52,76,66,65,86,83,4,98,51,3,2,81,99,103,96,74,111,5,6,91,113,102,67,31,35,34,33,32,116,

7,101,87,49,48,37,60,88,110,36,69,10,77,97,84,56,54,59,104,61,8,47,11,90,30,114,73,55,115,92,9,

120,13,12,38,29,107,100,72,78,19,79,15,14,119,39,28,108,62,85,70,18,20,16,118,106,40,27,26,58,

68,21,17,75,112,109,117,41,105,25,24,23,22,95,80,93,94,64,46,63,53,50,71,42,43,44,45,82,121,57

},

n8U = {

54,19,9,91,83,90,99,119,25,81,1,55,87,18,73,92,94,74,56,35,85,2,75,93,38,104,12,11,13,114,88,

120,3,97,41,39,32,103,112,111,22,105,5,4,43,42,108,36,40,89,106,21,82,6,98,44,72,80,118,15,16,

17,107,79,7,116,45,63,100,14,115,102,95,10,23,8,96,65,69,68,24,37,70,29,20,67,113,109,62,64,86,

84,27,26,28,117,58,59,60,53,50,49,48,101,30,66,51,52,110,61,78,71,76,47,46,31,33,34,57,77,121

},

n9U = {

83,9,91,57,62,18,119,79,50,1,102,15,11,120,96,86,19,113,114,92,2,3,109,61,100,116,14,13,12,75,

59,108,4,112,104,66,16,20,115,46,40,54,93,5,71,87,21,17,117,106,74,34,69,67,8,64,97,22,85,35,

36,10,38,76,90,118,27,26,23,99,89,98,77,7,68,73,84,28,72,25,24,94,107,88,33,47,48,105,29,110,

111,80,41,37,6,101,51,49,56,30,31,32,39,70,78,81,55,52,82,121,103,63,60,42,43,44,45,95,53,58,65

},

lAU = {

1,5,11,105,110,111,3,121,76,118,10,2,9,12,114,90,83,4,120,108,116,13,70,61,73,68,63,7,91,80,

56,88,14,109,79,51,104,6,53,8,72,55,119,15,103,106,50,35,112,52,92,34,54,17,16,99,98,94,29,36,

37,38,30,75,18,117,85,45,44,28,66,97,100,31,67,19,89,47,46,96,27,62,65,115,32,59,20,102,48,84,

77,26,43,69,95,33,74,21,101,49,60,81,71,42,57,86,93,23,22,87,58,78,82,64,41,40,39,25,24,113,107

},

lBU = {

1,4,5,120,112,3,121,113,66,116,10,2,11,12,86,101,96,84,81,67,117,14,89,111,103,45,24,8,13,72,

83,108,15,73,55,54,39,87,98,48,33,69,99,16,57,56,75,43,114,110,76,34,71,18,17,105,119,90,42,9,

25,19,94,30,20,118,63,74,61,41,68,77,92,46,49,22,78,58,51,50,40,65,104,82,35,70,23,93,97,52,102,

44,6,7,21,100,109,26,107,62,53,59,91,47,106,79,31,28,27,88,64,85,60,80,38,37,36,32,29,95,115

},

lCU = {

3,4,84,116,115,109,13,120,101,5,1,83,6,55,121,105,108,14,114,54,9,2,62,113,77,73,12,11,10,78,

85,76,74,52,118,69,18,23,49,107,7,65,88,75,51,26,25,19,89,50,103,86,63,80,79,71,27,61,20,87,117,

36,35,34,91,92,29,28,58,21,96,70,111,93,33,60,72,30,119,68,22,24,66,110,8,32,97,95,90,100,81,

104,17,16,15,31,106,67,44,98,48,47,112,64,37,99,40,41,42,43,102,82,46,45,39,38,53,59,57,56,94

},

lDU = {

54,74,1,120,2,83,3,111,94,102,27,71,17,16,119,35,96,4,5,104,117,87,106,18,103,34,23,22,118,6,7,

121,113,38,26,90,33,114,97,60,110,8,9,86,46,77,78,32,91,69,84,21,100,10,63,56,93,89,31,45,58,

95,20,105,11,68,59,81,66,30,92,79,75,19,101,12,57,64,99,80,29,112,70,40,109,14,13,41,76,85,47,

28,25,24,98,115,15,116,42,50,49,48,108,67,36,55,82,61,72,43,51,52,53,107,65,37,39,73,62,88,44

},

lEU = {

97,3,78,116,2,98,1,109,80,6,81,105,4,5,110,99,59,76,92,106,7,8,121,9,96,45,44,43,42,41,103,15,

112,11,10,47,35,117,94,113,100,17,16,111,12,101,62,34,65,66,82,19,18,119,93,13,107,88,33,30,

29,68,20,79,115,89,14,90,87,32,83,70,63,21,22,118,71,102,114,60,31,72,69,77,74,23,24,25,84,108,

48,40,39,38,37,36,95,120,26,55,50,49,91,64,52,58,73,67,85,27,57,75,51,104,56,53,54,86,61,46,28

},

lFU = {

1,104,3,113,2,111,102,117,4,109,5,74,21,20,98,75,100,65,95,110,7,6,118,22,119,45,32,34,33,35,

120,8,105,72,23,73,44,76,86,67,96,10,9,115,25,24,52,43,90,81,70,108,11,83,84,49,106,69,42,30,

31,91,13,12,107,121,53,92,99,41,101,112,78,14,26,27,28,88,82,68,40,103,17,16,15,116,97,29,61,58,

55,39,77,18,63,89,94,71,46,64,80,56,87,37,19,36,38,114,93,47,66,59,57,79,48,62,50,51,54,60,85

},

lGU = {

99,100,36,115,1,106,94,111,2,3,4,69,63,37,113,10,70,64,103,58,79,5,71,83,38,121,6,7,8,108,61,

87,81,62,76,97,11,18,40,85,50,59,84,89,34,66,80,12,116,41,82,51,56,60,73,33,96,92,15,118,39,29,

9,74,78,88,32,101,77,16,117,93,72,13,42,43,65,27,20,19,17,120,102,112,14,91,44,105,104,21,114,

119,30,31,28,35,98,45,46,54,22,57,107,109,52,48,67,55,53,47,86,23,24,25,26,90,49,110,75,95,68

},

lHU = {

96,74,6,120,7,67,3,107,1,87,103,111,11,8,121,92,86,4,118,2,5,113,100,12,114,32,59,73,81,22,63,

10,105,18,13,106,27,80,82,89,61,64,14,117,19,110,90,28,88,70,102,24,109,15,16,20,101,91,29,77,

25,78,21,97,115,17,33,35,36,30,85,68,83,62,104,112,23,55,72,76,31,56,57,71,60,75,84,34,99,98,

47,26,37,53,79,9,65,116,42,66,95,48,119,38,39,40,94,45,44,43,54,50,49,108,52,51,41,93,46,69,58

},

lIU = {

54,90,106,2,51,62,68,1,105,80,52,89,113,10,4,98,119,78,3,5,99,53,93,118,11,73,9,45,8,96,19,

108,91,112,13,12,60,84,44,100,61,20,82,83,77,14,101,117,58,43,57,92,21,22,69,87,15,120,38,46,42,

64,71,86,23,79,17,16,36,37,76,41,88,115,114,24,107,18,63,81,66,59,40,94,95,104,25,26,34,110,97,

103,7,39,6,74,65,109,27,35,47,48,121,116,111,75,31,30,29,28,55,72,49,50,67,85,33,32,102,70,56

},

lJU = {

26,103,76,108,68,3,58,117,6,1,105,27,79,115,110,116,4,92,114,7,2,5,28,88,63,109,89,8,59,30,81,

83,33,29,98,62,78,10,9,104,31,94,82,74,91,71,13,12,11,120,57,32,99,95,70,101,15,14,46,69,107,

75,34,72,86,52,65,16,85,41,102,121,56,35,49,50,51,67,17,93,40,47,119,48,36,96,55,53,100,18,19,

84,39,38,37,113,80,66,77,64,54,20,21,97,118,60,87,44,45,61,73,112,111,22,23,24,25,42,43,106,90

},

lKU = {

117,1,11,120,21,100,79,66,67,86,3,5,2,12,121,41,81,106,107,85,104,7,6,89,112,31,63,69,92,32,

93,76,8,9,99,83,30,101,77,22,97,61,82,10,115,91,87,29,114,4,80,60,58,17,16,48,108,78,28,24,23,

98,73,64,18,109,47,95,70,27,94,68,15,103,20,19,113,46,45,62,26,96,75,74,14,33,90,110,111,43,42,

25,40,84,34,13,88,72,119,102,44,59,118,39,53,35,49,50,51,71,65,54,55,116,38,37,36,57,52,56,105

},

lLU = {

1,5,11,108,72,3,120,114,112,34,91,2,9,12,83,89,4,100,110,115,55,92,6,117,116,39,46,7,8,119,64,

56,93,28,29,85,40,68,53,10,61,95,106,96,109,30,102,41,67,111,13,14,15,90,79,70,31,80,42,52,104,

101,32,16,81,62,105,94,71,43,51,121,99,33,17,18,19,86,82,50,44,60,75,73,58,57,66,20,103,113,

47,45,38,37,36,35,78,118,21,74,54,48,98,63,59,84,69,77,23,22,87,107,49,88,65,97,27,26,25,24,76

},

lMU = {

115,89,1,116,2,3,5,121,13,120,86,113,7,4,117,92,12,79,118,15,16,98,9,8,104,32,84,109,75,38,90,

17,105,10,87,85,39,31,108,43,44,100,18,106,14,96,88,41,94,6,81,36,93,19,103,30,107,95,34,83,71,

76,35,99,20,21,45,46,78,29,70,101,68,11,82,119,22,102,47,48,33,65,66,67,37,72,111,23,97,61,55,

40,49,73,64,42,52,114,24,74,63,56,110,50,69,59,112,27,26,25,62,60,57,80,51,53,54,77,28,91,58

},

lNU = {

101,96,1,119,2,3,11,118,13,117,90,91,7,4,112,107,12,82,121,16,17,102,9,8,79,33,77,113,95,41,93,

18,105,14,71,85,32,5,114,97,42,108,19,84,15,99,98,38,72,6,76,43,94,20,110,104,88,100,39,103,

106,10,34,44,21,22,65,64,63,40,61,74,57,35,80,109,23,73,68,83,28,78,46,45,36,70,120,24,75,67,

49,27,48,47,89,37,92,115,25,66,51,50,116,56,81,55,111,30,29,26,58,52,59,87,62,69,54,53,31,86,60

},

lOU = {

84,118,3,100,1,86,2,85,13,121,58,105,78,4,108,42,57,92,79,14,15,77,120,6,5,115,28,29,30,114,89,

16,119,94,7,81,36,107,87,43,37,66,17,96,104,8,112,35,67,69,111,38,90,18,19,10,9,95,33,97,63,

116,39,72,117,20,11,102,68,32,48,62,98,40,76,113,21,12,106,103,31,110,99,44,41,80,23,22,24,101,

71,45,25,26,27,88,64,109,91,34,75,74,82,93,46,49,50,51,52,65,73,61,55,54,53,47,59,60,56,70,83

},

lPU = {

87,2,11,112,104,71,91,103,1,86,3,9,5,12,115,63,69,95,96,83,120,4,50,77,121,40,32,34,7,88,119,

97,6,52,55,100,39,70,89,101,33,109,13,10,64,105,93,38,90,94,42,8,74,14,49,65,80,62,37,28,31,29,

107,111,15,106,57,48,47,36,116,81,117,18,17,16,118,59,92,82,35,78,99,20,19,26,76,85,98,102,43,

30,41,22,21,66,27,113,108,46,45,44,110,24,23,75,72,51,67,114,84,60,56,79,25,58,73,61,53,54,68

},

lQU = {

107,3,59,101,10,106,92,120,11,1,61,98,4,65,89,93,86,103,117,9,2,5,113,12,84,115,6,7,8,114,82,

104,26,21,14,20,15,112,95,72,36,79,91,116,22,110,69,16,85,80,94,35,44,45,71,23,87,88,17,102,

78,66,34,62,46,68,24,111,83,18,121,13,74,33,99,47,48,25,118,40,19,37,55,27,32,109,119,90,96,97,

53,100,28,29,30,31,77,60,70,75,58,54,73,38,81,63,76,50,51,52,67,57,56,108,39,41,42,43,49,105,64

},

lRU = {

1,4,5,119,3,103,113,112,120,81,10,2,11,12,116,41,91,89,105,99,92,13,86,87,121,40,6,7,8,108,114,

80,14,84,101,97,37,110,85,90,17,19,16,15,70,53,51,36,109,68,79,18,20,61,106,75,54,104,39,9,31,

26,111,21,83,118,57,56,76,38,93,69,107,22,25,33,95,65,63,64,35,82,62,55,23,78,50,94,98,102,46,

34,115,96,27,24,42,43,44,67,88,47,77,71,29,28,73,74,72,45,66,52,48,100,32,30,49,58,59,60,117

},

lSU = {

4,100,6,121,68,13,83,102,64,109,1,5,118,7,9,98,115,110,112,92,3,2,114,87,107,16,12,11,10,17,

105,104,88,103,81,84,14,59,78,62,8,18,91,73,119,21,20,15,82,95,108,97,19,28,67,113,22,96,43,41,

42,40,94,66,29,85,24,23,32,120,101,99,44,36,76,30,86,25,89,93,53,70,80,72,37,61,31,60,26,63,106,

117,38,39,35,45,58,79,65,27,33,74,116,54,50,51,52,55,90,69,111,34,46,47,48,49,56,71,57,77,75

},

lTU = {

1,2,11,97,79,116,75,106,107,3,74,5,9,12,94,60,117,66,115,108,4,81,93,85,103,37,40,47,39,38,105,

6,78,100,83,112,70,59,46,58,65,8,7,63,32,31,30,111,71,45,62,101,10,110,68,33,73,29,91,72,44,

64,104,13,96,52,34,120,28,27,99,43,119,15,14,121,51,118,92,114,26,56,42,88,16,35,36,48,82,54,

53,25,90,41,61,17,86,113,49,89,55,102,24,23,109,19,18,87,95,50,84,67,77,69,22,21,20,76,98,80,57

},

lUU = {

6,116,1,118,17,70,5,112,7,114,105,98,3,2,121,23,71,102,119,8,9,115,88,4,111,24,44,79,80,30,94,

10,107,96,21,104,28,103,73,91,31,101,11,12,78,22,37,27,110,69,68,32,106,109,13,47,45,84,26,87,

83,77,33,62,113,14,48,117,75,25,82,67,92,34,100,16,15,49,120,85,29,86,59,39,35,38,36,95,50,99,

58,108,20,19,18,90,46,97,66,51,52,53,76,57,40,56,74,54,93,65,60,72,61,89,42,41,43,81,55,63,64

},

lVU = {

101,92,6,113,4,70,5,83,15,116,66,118,8,7,110,40,68,87,93,16,17,107,119,9,56,35,41,71,108,34,84,

18,96,114,10,69,27,90,72,58,30,104,19,78,12,11,85,26,98,89,75,31,115,20,109,13,111,91,25,112,

64,81,32,99,21,22,14,117,100,24,88,63,45,33,43,121,23,38,105,97,77,1,67,2,94,42,120,28,39,86,

65,106,73,3,95,102,37,36,29,44,46,47,79,74,53,60,82,54,80,52,59,76,48,49,50,51,55,57,62,103,61

},

lWU = {

104,73,1,121,2,3,11,118,13,117,108,101,7,4,120,89,12,94,119,16,17,92,9,8,114,27,99,41,105,37,

103,18,110,14,86,65,28,71,106,68,36,88,19,90,15,45,50,40,83,113,81,35,87,20,102,98,96,109,39,70,

60,78,34,44,21,22,75,84,79,38,64,6,85,43,67,107,23,74,80,93,32,10,100,5,42,95,116,24,66,76,51,

33,63,97,47,26,72,115,25,58,62,52,111,61,77,48,112,31,30,29,57,54,53,82,59,56,49,69,55,91,46

},

lXU = {

116,2,1,100,3,6,121,104,73,52,93,9,5,106,114,4,7,8,113,97,96,112,11,12,120,29,118,111,14,10,69,

99,78,85,110,83,30,90,95,117,13,15,16,17,64,39,81,82,48,79,49,94,58,59,18,53,38,37,84,55,50,

107,89,72,67,19,62,103,36,91,46,54,47,51,86,75,20,70,119,35,31,108,102,115,23,25,22,21,60,57,

56,32,92,76,26,24,66,77,105,61,88,71,34,33,28,27,109,68,65,87,80,98,45,44,74,63,40,41,42,43,101

},

lYU = {

94,1,61,85,3,115,4,118,79,49,62,5,2,55,114,42,80,6,96,111,103,57,9,119,89,31,43,117,10,7,92,

101,53,11,108,75,30,121,60,120,8,12,74,52,110,91,66,44,27,48,26,113,13,82,51,72,84,46,45,102,

32,95,116,14,15,50,41,69,59,47,76,33,109,86,77,16,58,40,39,54,70,107,34,78,64,100,17,68,104,38,

67,105,97,35,112,20,19,18,56,87,37,36,29,28,93,88,21,81,106,65,98,83,63,71,25,24,23,22,73,90,99

},

lZU = {

94,86,5,4,107,108,75,115,1,2,74,76,7,6,104,106,97,72,99,3,50,51,112,9,111,31,32,33,34,35,120,

101,53,71,10,61,96,84,82,66,36,56,55,54,30,11,12,105,81,91,60,87,70,65,59,37,100,13,14,17,16,

103,117,92,83,79,38,98,95,119,15,18,19,25,89,88,67,39,109,116,24,42,118,113,26,27,28,29,40,110,

121,23,22,21,20,8,114,102,90,41,62,63,78,85,43,64,77,52,49,57,93,69,68,73,80,44,45,46,47,48,58

};

 

t_drain upC = { // ASCII table of pointers to up draining character squares.

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

spU, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// sp ! " # $ % & ' ( ) * + , - . /

lOU, n1U, n2U, n3U, n4U, n5U, n6U, n7U, n8U, n9U, NULL,NULL,NULL,NULL,NULL,NULL,

// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

NULL,lAU, lBU, lCU, lDU, lEU, lFU, lGU, lHU, lIU, lJU, lKU, lLU, lMU, lNU, lOU,

// @ A B C D E F G H I J K L M N O

lPU, lQU, lRU, lSU, lTU, lUU, lVU, lWU, lXU, lYU, lZU, NULL,NULL,NULL,NULL,NULL,

// P Q R S T U V W X Y Z [ \ ] ^ _

NULL,lAU, lBU, lCU, lDU, lEU, lFU, lGU, lHU, lIU, lJU, lKU, lLU, lMU, lNU, lOU,

// ` a b c d e f g h i j k l m n o

lPU, lQU, lRU, lSU, lTU, lUU, lVU, lWU, lXU, lYU, lZU, NULL,NULL,NULL,NULL,NULL

// p q r s t u v w x y z { | } ~ DEL

};

 

t_chSquare // Character squares that drain down.

spD = {

34,27,26,25,24,88,119,100,120,77,31,49,99,116,98,23,22,21,70,114,30,29,50,66,63,56,113,71,20,

45,78,81,28,121,54,52,53,117,101,19,18,17,103,16,86,89,43,64,95,73,107,72,13,14,15,46,44,39,42,

112,58,104,57,12,67,90,48,60,38,61,115,55,51,65,11,80,87,97,111,37,36,35,108,8,9,10,102,118,41,

85,106,79,32,6,7,62,93,68,92,40,33,76,74,4,5,105,82,109,47,96,59,3,75,83,1,84,110,91,94,2,69

},

n1D = {

76,52,51,37,38,113,55,48,49,50,102,70,61,57,36,56,108,54,47,53,64,65,83,81,22,35,60,33,58,46,

45,105,103,92,94,21,86,3,32,62,89,44,34,114,99,101,20,63,77,31,42,41,66,24,107,118,15,19,96,91,

30,80,40,39,23,120,111,14,73,74,90,29,98,75,72,18,17,7,13,93,88,69,28,59,104,78,116,16,6,112,

106,68,26,27,25,84,97,110,10,5,11,100,87,79,121,67,95,85,12,9,4,117,109,1,82,119,71,2,43,115,8

},

n2D = {

95,109,36,35,34,33,32,31,85,80,101,63,82,37,75,70,68,59,30,56,60,71,62,108,77,114,20,21,22,29,

88,83,47,57,119,103,8,23,112,102,24,38,39,46,27,92,72,18,19,104,107,7,79,98,48,26,117,16,17,116,

6,1,118,99,105,50,25,14,15,97,52,93,76,120,61,67,51,66,13,58,45,84,69,64,110,55,54,53,86,10,

111,41,42,43,44,40,87,78,89,91,4,81,121,115,94,90,49,12,5,9,73,3,65,100,96,28,74,113,11,2,106

},

n3D = {

79,117,46,42,41,40,43,44,45,84,90,56,55,51,66,64,39,67,102,54,58,59,114,118,100,113,12,13,14,

30,31,32,94,74,95,73,24,28,101,115,23,71,33,34,17,20,21,25,96,108,116,22,107,104,35,16,82,86,

89,98,18,19,47,75,105,36,15,69,68,65,92,80,106,26,53,60,37,11,10,121,29,62,112,48,27,97,61,93,

109,9,99,49,6,7,8,120,78,83,103,70,5,4,88,87,76,63,119,57,50,52,110,91,2,81,85,77,72,111,3,1,38

},

n4D = {

54,51,50,74,77,60,79,56,47,61,62,59,58,49,75,64,57,86,53,32,71,67,85,82,21,22,52,36,37,83,31,

108,114,119,19,20,121,35,120,38,112,30,29,28,17,18,106,34,92,89,39,68,65,116,27,16,98,117,33,

44,43,41,42,93,118,26,15,14,13,103,88,104,40,69,87,113,25,84,99,10,7,109,110,46,81,78,23,24,91,

96,90,6,5,48,45,97,70,12,111,76,73,100,102,4,3,115,8,72,11,107,55,63,95,94,101,1,105,2,66,9,80

},

n5D = {

83,84,96,86,74,82,29,28,27,26,56,65,63,55,68,61,60,64,102,69,25,39,104,112,54,43,40,37,42,41,

103,24,71,72,76,87,6,62,75,85,106,22,23,57,70,45,46,7,77,67,73,111,21,95,59,88,44,110,38,10,36,

35,118,20,114,58,32,33,93,90,66,79,91,17,19,98,53,31,94,101,97,80,81,18,16,50,51,52,30,117,15,

11,12,13,14,121,119,120,99,4,2,9,116,100,107,115,8,113,48,49,92,1,5,109,89,34,105,3,108,47,78

},

n6D = {

65,58,53,95,45,44,43,42,60,63,103,121,82,52,55,81,78,70,39,32,31,30,56,49,51,101,6,37,41,80,

111,110,29,105,48,47,33,88,107,94,24,25,72,28,84,73,68,7,77,98,89,99,23,26,27,118,90,76,38,10,

36,35,85,22,97,64,8,67,69,34,74,106,117,17,21,87,71,5,93,54,40,46,115,20,16,66,104,112,4,108,59,

75,12,13,14,116,100,61,109,3,2,92,114,113,19,86,96,120,11,15,102,1,50,79,119,18,62,57,91,9,83

},

n7D = {

54,24,25,26,27,74,75,70,95,90,111,53,23,101,86,56,79,107,40,41,42,43,85,22,117,31,35,34,33,32,

62,102,118,60,21,73,37,57,81,78,36,55,58,115,87,20,19,116,61,119,106,8,44,45,46,65,113,18,17,98,

38,9,39,82,71,121,64,96,28,16,15,13,112,104,109,108,6,59,91,29,68,89,12,120,77,52,69,5,49,114,

66,97,94,11,14,88,51,83,4,48,80,103,84,76,110,10,105,50,2,3,47,67,92,93,63,100,7,72,30,1,99

},

n8D = {

78,71,76,47,46,31,33,34,57,77,121,53,50,49,48,101,30,66,51,52,110,61,62,64,86,84,27,26,28,117,

58,59,60,65,69,68,24,37,70,29,20,67,113,109,45,63,100,14,115,102,95,10,23,8,96,44,72,80,118,15,

16,17,107,79,7,116,43,42,108,36,40,89,106,21,82,6,98,97,41,39,32,103,112,111,22,105,5,4,75,93,

38,104,12,11,13,114,88,120,3,55,87,18,73,92,94,74,56,35,85,2,54,19,9,91,83,90,99,119,25,81,1

},

n9D = {

70,114,48,47,46,116,28,29,30,71,72,44,64,93,68,45,87,27,69,31,57,86,43,60,111,108,11,15,6,115,

49,50,103,42,58,81,16,26,101,100,40,65,59,83,39,32,25,17,119,74,94,34,53,75,109,76,107,24,51,

35,36,10,38,89,99,106,73,52,23,97,113,88,62,7,85,63,8,91,56,22,20,21,104,118,33,105,96,5,84,78,

95,90,14,13,12,117,66,98,4,55,41,67,80,121,19,112,110,61,2,3,54,9,82,77,120,18,102,79,37,1,92

},

lAD = {

48,47,46,45,44,55,58,63,80,85,100,49,86,57,87,43,72,25,24,23,114,91,50,82,95,66,42,7,61,98,22,

92,56,104,105,103,93,6,74,8,118,21,20,19,81,65,62,35,40,60,88,34,110,78,18,90,94,89,29,36,37,

38,30,102,109,17,54,53,106,28,120,69,68,31,111,15,16,75,52,51,27,64,71,97,32,112,14,76,117,73,

39,26,67,77,59,33,83,13,84,2,5,12,119,96,108,99,101,4,10,115,1,9,11,116,113,41,70,107,3,121,79

},

lBD = {

64,85,60,80,38,37,36,32,29,95,115,62,53,59,91,47,106,79,31,28,27,88,97,52,102,44,6,7,21,100,

109,26,107,58,51,50,40,65,104,82,35,70,23,93,63,74,61,41,68,77,92,46,49,22,78,105,119,90,42,9,

25,19,94,30,20,118,57,56,75,43,114,110,76,34,71,18,17,73,55,54,39,87,98,48,33,69,99,16,89,111,

103,45,24,8,13,72,83,108,15,2,11,12,86,101,96,84,81,67,117,14,1,4,5,120,112,3,121,113,66,116,10

},

lCD = {

102,82,46,45,39,38,53,59,57,56,94,98,48,47,112,64,37,99,40,41,42,43,90,100,81,104,17,16,15,31,

106,67,44,30,119,68,22,24,66,110,8,32,97,95,29,28,58,21,96,70,111,93,33,60,72,71,27,61,20,87,

117,36,35,34,91,92,51,26,25,19,89,50,103,86,63,80,79,52,118,69,18,23,49,107,7,65,88,75,62,113,

77,73,12,11,10,78,85,76,74,83,6,55,121,105,108,14,114,54,9,2,3,4,84,116,115,109,13,120,101,5,1

},

lDD = {

51,52,53,107,65,37,39,73,62,88,44,50,49,48,108,67,36,55,82,61,72,43,76,85,47,28,25,24,98,115,

15,116,42,64,99,80,29,112,70,40,109,14,13,41,59,81,66,30,92,79,75,19,101,12,57,56,93,89,31,45,

58,95,20,105,11,68,46,77,78,32,91,69,84,21,100,10,63,38,26,90,33,114,97,60,110,8,9,86,106,18,

103,34,23,22,118,6,7,121,113,71,17,16,119,35,96,4,5,104,117,87,54,74,1,120,2,83,3,111,94,102,27

},

lED = {

57,75,51,104,56,53,54,86,61,46,28,55,50,49,91,64,52,58,73,67,85,27,84,108,48,40,39,38,37,36,

95,120,26,102,114,60,31,72,69,77,74,23,24,25,14,90,87,32,83,70,63,21,22,118,71,13,107,88,33,30,

29,68,20,79,115,89,12,101,62,34,65,66,82,19,18,119,93,11,10,47,35,117,94,113,100,17,16,111,121,

9,96,45,44,43,42,41,103,15,112,105,4,5,110,99,59,76,92,106,7,8,97,3,78,116,2,98,1,109,80,6,81

},

lFD = {

62,78,49,105,71,90,95,32,31,30,28,51,50,48,74,54,64,65,55,116,67,27,52,101,47,41,42,43,44,45,

121,109,26,53,61,59,40,58,68,69,46,118,76,23,63,89,75,39,56,86,81,19,120,21,22,82,117,102,38,33,

34,115,18,17,16,99,29,25,60,37,73,87,84,72,119,15,70,77,24,107,36,88,10,111,97,13,14,94,79,12,

108,35,96,6,4,104,8,113,106,57,11,9,114,80,92,2,98,5,110,93,66,103,7,112,20,91,1,85,3,100,83

},

lGD = {

108,51,26,86,101,53,33,34,36,37,106,77,71,25,93,58,59,32,107,54,38,57,94,79,24,121,6,7,8,104,

103,40,85,110,61,23,11,27,76,97,50,80,41,95,60,49,48,12,112,74,84,102,43,42,45,90,72,120,15,88,

39,29,9,44,119,46,65,63,81,16,83,55,118,13,62,68,47,20,21,22,17,98,91,69,14,99,105,115,19,70,

89,111,30,31,28,35,92,100,66,18,52,96,75,67,73,64,87,56,78,5,10,82,117,114,1,113,109,116,2,3,4

},

lHD = {

58,69,46,93,41,51,52,108,49,50,54,43,44,45,94,40,39,38,119,48,95,66,42,116,65,9,79,53,37,26,47,

98,99,34,84,75,60,71,57,56,31,76,72,55,23,112,104,62,83,68,85,30,36,35,33,17,115,97,21,78,25,

77,29,91,101,20,16,15,109,24,102,70,88,28,90,110,19,117,14,64,61,89,82,80,27,106,13,18,105,10,

63,22,81,73,59,32,114,12,100,113,5,2,118,4,86,92,121,8,11,111,103,87,1,107,3,67,7,120,6,74,96

},

lID = {

56,70,102,32,33,85,67,50,49,72,55,28,29,30,31,75,111,116,121,48,47,35,27,109,65,74,6,39,7,103,

97,110,34,26,25,104,95,94,40,59,66,81,63,18,107,24,114,115,88,41,76,37,36,16,17,79,23,86,71,64,

42,46,38,120,15,87,69,22,21,92,57,43,58,117,101,14,77,83,82,20,61,100,44,84,60,12,13,112,91,

108,19,96,8,45,9,73,11,118,93,53,99,5,3,78,119,98,4,10,113,89,52,80,105,1,68,62,51,2,106,90,54

},

lJD = {

68,44,39,78,60,92,24,66,67,74,59,112,119,28,27,26,22,23,102,105,52,55,88,62,61,85,69,21,108,30,

47,49,51,91,113,57,18,19,20,46,31,86,110,80,90,14,16,17,97,65,118,32,77,103,42,94,13,56,95,79,

53,48,34,82,76,41,99,12,71,15,101,75,104,35,81,38,40,10,11,87,37,93,107,54,45,114,7,106,9,117,

121,120,29,33,36,111,5,6,84,8,50,63,64,73,83,109,89,4,58,70,2,116,72,115,25,100,1,96,3,98,43

},

lKD = {

84,57,59,116,39,38,46,67,44,45,76,66,56,63,118,40,37,36,42,43,68,102,54,53,109,31,65,73,35,32,

47,64,108,99,52,51,30,83,90,22,34,33,58,119,62,55,60,29,106,4,112,97,20,19,107,89,82,61,28,24,

23,50,100,81,18,115,96,111,94,27,103,95,15,49,48,17,16,9,104,72,26,75,77,105,14,87,92,10,6,98,

79,25,74,86,88,13,114,80,8,5,2,12,120,41,78,91,113,85,117,7,101,1,11,121,21,70,71,110,69,93,3

},

lLD = {

50,51,52,117,19,18,65,63,58,106,72,49,73,57,121,60,17,46,47,48,99,54,45,61,55,31,71,16,93,81,

74,91,53,44,90,66,30,83,15,14,85,108,113,23,43,97,80,29,64,101,13,12,95,115,22,42,114,110,28,

120,79,116,11,10,20,21,41,40,56,27,59,69,82,96,9,105,87,107,39,38,26,102,112,78,68,8,7,86,104,

103,92,25,32,33,34,35,98,6,109,76,2,3,118,37,100,94,84,75,5,77,70,1,62,119,24,111,36,89,88,4,67

},

lMD = {

57,54,53,82,59,56,49,69,55,91,46,58,62,52,111,61,77,48,112,31,30,29,66,76,51,33,63,97,47,26,72,

115,25,74,80,93,32,10,100,5,42,95,116,24,75,84,79,38,64,6,85,43,67,107,23,98,96,109,39,70,60,

78,34,44,21,22,15,45,50,40,83,113,81,35,87,20,102,14,86,65,28,71,106,68,36,88,19,90,9,8,114,27,

99,41,105,37,103,18,110,101,7,4,120,89,12,94,119,16,17,92,104,73,1,121,2,3,11,118,13,117,108

},

lND = {

66,59,61,76,54,53,52,77,31,92,50,64,57,63,118,75,65,51,93,30,29,26,78,56,85,33,47,46,45,41,95,

120,25,58,55,49,32,5,91,89,42,112,114,24,94,74,87,38,48,6,80,43,72,106,23,100,111,84,39,110,

96,10,34,44,21,22,15,67,68,40,62,98,60,35,105,20,101,14,73,70,28,69,113,86,36,82,19,81,9,8,99,

27,97,88,108,37,71,18,109,90,7,4,121,102,12,79,116,16,17,107,83,104,1,119,2,3,11,117,13,115,103

},

lOD = {

83,70,56,60,59,47,53,54,55,61,73,65,52,51,50,49,46,93,82,74,75,34,91,109,64,88,27,26,25,45,71,

101,24,22,23,80,41,44,99,110,31,103,106,12,21,113,76,40,98,62,48,32,68,102,11,20,117,72,39,116,

63,97,33,95,9,10,19,18,90,38,111,69,67,35,112,8,104,96,17,66,37,43,87,107,36,81,7,94,119,16,

89,114,30,29,28,115,5,6,120,77,15,14,79,92,57,42,108,4,78,105,58,121,13,85,2,86,1,100,3,118,84

},

lPD = {

67,63,62,75,73,47,66,49,48,44,77,104,92,61,120,43,42,41,27,26,25,90,91,87,60,40,32,34,33,102,

117,24,51,81,59,85,39,86,88,74,7,79,23,50,101,58,45,38,98,114,118,6,20,21,52,96,57,99,37,4,31,

29,110,19,100,89,54,53,46,36,119,95,84,17,18,78,71,56,80,83,35,97,82,15,16,68,69,70,11,72,113,

30,108,13,14,105,76,65,64,9,28,12,112,8,10,103,121,107,106,55,1,22,5,109,3,115,94,111,93,116,2

},

lQD = {

61,100,43,42,41,40,56,108,58,60,62,25,109,44,99,59,39,55,92,46,51,52,24,114,85,116,4,35,10,38,

45,98,102,23,22,21,19,112,76,75,36,117,91,79,54,104,57,7,88,66,65,30,67,63,70,68,110,64,8,81,

93,72,31,47,48,49,53,50,69,18,107,13,97,32,77,73,82,74,17,20,6,113,83,29,33,111,84,101,90,16,

95,115,26,27,28,34,80,89,71,103,15,86,120,37,94,78,119,12,5,2,96,14,87,121,3,105,106,118,11,9,1

},

lRD = {

66,76,52,51,50,48,60,61,59,81,67,63,54,53,101,49,47,56,57,58,103,30,78,102,69,42,19,20,25,98,

79,115,24,34,35,46,41,96,71,108,31,80,117,12,33,113,65,40,74,64,55,32,70,114,11,23,120,110,39,

44,45,36,116,119,9,10,22,18,89,38,91,77,111,21,84,8,112,94,17,85,37,86,82,100,26,28,7,109,88,

16,75,43,68,72,90,27,87,6,99,97,15,14,121,92,83,29,107,4,5,104,73,105,13,118,2,62,1,95,3,106,93

},

lSD = {

75,77,57,71,56,49,48,47,46,34,111,69,90,55,52,51,50,54,116,74,33,27,65,79,58,45,35,39,38,117,

106,63,26,60,31,61,37,72,80,70,53,93,89,25,86,30,76,36,44,99,101,120,32,23,24,85,29,66,94,40,

42,41,43,96,22,113,67,28,19,97,108,95,82,15,20,21,119,73,91,18,8,62,78,59,14,84,81,103,88,104,

105,17,10,11,12,16,107,87,114,2,3,92,112,110,115,98,9,7,118,5,1,109,64,102,83,13,68,121,6,100,4

},

lTD = {

109,46,45,44,52,95,48,49,57,62,64,72,67,60,43,50,99,47,96,59,24,54,112,105,114,7,28,37,30,8,

106,23,101,93,81,63,88,55,36,51,103,21,22,58,110,76,42,41,107,35,53,19,20,100,68,94,69,73,40,

39,34,61,18,78,86,79,27,31,65,56,84,33,108,17,70,98,82,26,85,90,89,83,32,38,16,15,117,80,25,91,

102,74,66,29,71,111,14,13,75,2,11,12,97,104,120,77,119,113,10,6,1,9,5,92,3,121,87,115,118,116,4

},

lUD = {

55,82,45,93,59,43,58,76,47,56,57,54,78,39,81,51,42,41,77,46,101,61,53,100,38,28,69,52,40,29,

44,120,98,50,121,88,27,71,63,66,30,35,17,103,49,113,111,26,73,67,96,31,74,16,15,48,36,37,25,83,

86,89,32,106,115,14,68,22,105,24,75,70,64,33,85,112,13,87,5,114,23,92,90,94,34,109,11,12,62,4,

91,117,20,19,18,118,110,10,102,80,3,2,119,72,79,84,116,8,9,99,65,107,1,108,6,60,21,95,7,104,97

},

lVD = {

69,63,50,67,45,42,41,55,76,77,86,95,58,49,47,46,48,40,51,72,103,62,119,113,70,35,71,79,39,34,

38,37,36,97,91,54,27,52,57,59,30,92,89,23,22,99,56,26,53,73,80,31,106,105,20,21,110,85,25,66,

104,75,32,118,17,18,8,7,87,24,107,84,74,33,120,16,111,121,6,68,114,28,78,29,90,14,15,108,116,4,

5,93,61,19,65,94,13,101,100,2,3,64,98,60,44,81,109,12,102,96,1,117,83,115,82,43,88,112,10,9,11

},

lWD = {

62,60,57,80,51,53,54,77,28,91,58,74,63,56,110,50,69,59,112,27,26,25,97,61,55,40,49,73,64,42,

52,114,24,102,47,48,33,65,66,67,37,72,111,23,45,46,78,29,70,101,68,11,82,119,22,30,107,95,34,

83,71,76,35,99,20,21,14,96,88,41,94,6,81,36,93,19,103,10,87,85,39,31,108,43,44,100,18,106,9,8,

104,32,84,109,75,38,90,17,105,113,7,4,117,92,12,79,118,15,16,98,115,89,1,116,2,3,5,121,13,120,86

},

lXD = {

80,98,45,44,74,63,40,41,42,43,101,61,88,71,34,33,28,27,109,68,65,87,60,57,56,32,92,76,26,24,66,

77,105,70,119,35,31,108,102,115,23,25,22,21,62,103,36,91,46,54,47,51,86,75,20,53,38,37,84,55,

50,107,89,72,67,19,64,39,81,82,48,79,49,94,58,59,18,85,110,83,30,90,95,117,13,15,16,17,11,12,

120,29,118,111,14,10,69,99,78,9,5,106,114,4,7,8,113,97,96,112,116,2,1,100,3,6,121,104,73,52,93

},

lYD = {

98,112,20,22,23,24,25,73,70,109,95,63,18,19,107,87,84,36,37,48,91,81,55,17,117,31,79,78,51,29,

56,92,66,54,16,72,30,80,90,110,28,59,85,47,53,15,105,118,27,77,26,38,60,106,46,49,14,13,121,119,

32,39,102,93,44,45,65,104,12,120,75,33,40,41,42,43,96,64,76,10,8,71,34,94,99,58,89,68,61,116,

108,7,103,35,50,74,97,9,11,57,100,113,6,4,115,114,88,67,2,5,52,83,82,101,3,69,86,62,21,1,111

},

lZD = {

58,48,47,46,45,44,80,73,68,69,93,57,49,52,77,64,43,85,78,63,62,41,90,102,114,8,20,21,22,23,121,

110,40,29,28,27,26,113,118,42,24,116,109,39,67,88,89,25,19,18,15,119,95,98,38,79,83,92,117,103,

16,17,14,13,100,37,59,65,70,87,60,91,81,105,12,11,30,54,55,56,36,66,82,84,96,61,10,71,53,101,

120,35,34,33,32,31,111,9,112,51,50,3,99,72,97,106,104,6,7,76,74,2,1,115,75,108,107,4,5,86,94

};

 

t_drain downC = { // ASCII table of pointers to down draining character squares.

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

spD, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,

// sp ! " # $ % & ' ( ) * + , - . /

lOD, n1D, n2D, n3D, n4D, n5D, n6D, n7D, n8D, n9D, NULL,NULL,NULL,NULL,NULL,NULL,

// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

NULL,lAD, lBD, lCD, lDD, lED, lFD, lGD, lHD, lID, lJD, lKD, lLD, lMD, lND, lOD,

// @ A B C D E F G H I J K L M N O

lPD, lQD, lRD, lSD, lTD, lUD, lVD, lWD, lXD, lYD, lZD, NULL,NULL,NULL,NULL,NULL,

// P Q R S T U V W X Y Z [ \ ] ^ _

NULL,lAD, lBD, lCD, lDD, lED, lFD, lGD, lHD, lID, lJD, lKD, lLD, lMD, lND, lOD,

// ` a b c d e f g h i j k l m n o

lPD, lQD, lRD, lSD, lTD, lUD, lVD, lWD, lXD, lYD, lZD, NULL,NULL,NULL,NULL,NULL

// p q r s t u v w x y z { | } ~ DEL

};

 

// Better H squares for cells with more than 1 drainage direction.

t_chSquare

lHLD = {

16,46,47,103,55,80,52,105,54,60,53,15,90,56,116,51,50,49,115,42,43,44,1,2,109,23,100,113,45,27,

41,111,99,71,11,39,26,84,102,63,24,68,107,76,82,12,65,28,114,40,61,30,62,108,69,83,86,74,38,25,

34,21,37,96,110,67,48,72,70,29,93,101,104,32,92,10,20,95,89,85,35,79,22,78,33,88,9,58,73,87,

94,36,59,19,66,31,121,8,77,106,112,18,120,6,13,75,119,4,7,91,81,64,14,117,5,97,57,118,3,98,17

},

lHLR = {

77,95,63,79,41,40,34,33,32,94,83,115,12,15,87,42,110,35,108,21,20,106,5,10,90,51,100,121,120,

50,89,19,16,82,85,59,52,61,81,65,49,62,72,3,2,102,70,53,60,98,75,48,68,91,4,92,112,74,54,6,7,8,

47,67,105,99,84,107,80,55,71,88,64,46,66,9,1,11,13,58,56,76,38,78,45,73,109,114,14,17,113,57,

118,31,119,44,117,23,18,103,22,24,101,69,29,30,104,37,36,116,86,96,25,26,27,28,43,97,39,93,111

},

lHLU = {

81,60,14,120,5,101,54,117,3,99,17,97,111,18,119,6,13,77,121,4,7,98,91,89,83,36,73,19,65,31,114,

8,62,93,78,74,35,88,22,71,33,100,9,68,48,66,84,29,85,106,105,32,86,10,20,90,102,72,38,25,34,21,

37,75,110,67,59,12,64,28,107,40,79,30,87,96,69,80,11,39,26,82,113,53,24,63,104,76,1,2,118,23,

92,112,45,27,41,115,95,15,94,58,109,51,50,49,116,42,43,44,16,46,47,108,57,61,52,103,56,70,55

},

lHRD = {

53,60,54,105,52,80,55,103,47,46,16,44,43,42,115,49,50,51,116,56,90,15,99,111,41,27,45,113,100,

23,109,2,1,76,107,68,24,63,102,84,26,39,11,71,69,108,62,30,61,40,114,28,65,12,82,67,110,96,37,

21,34,25,38,74,86,83,20,10,92,32,104,101,93,29,70,72,48,58,9,88,33,78,22,79,35,85,89,95,77,8,

121,31,66,19,59,36,94,87,73,91,7,4,119,75,13,6,120,18,112,106,17,98,3,118,57,97,5,117,14,64,81

},

lHRU = {

17,99,3,117,54,101,5,120,14,60,81,98,7,4,121,77,13,6,119,18,111,97,62,8,114,31,65,19,73,36,83,

89,91,68,9,100,33,71,22,88,35,74,78,93,20,10,86,32,105,106,85,29,84,66,48,67,110,75,37,21,34,

25,38,72,102,90,69,96,87,30,79,40,107,28,64,12,59,76,104,63,24,53,113,82,26,39,11,80,95,115,41,

27,45,112,92,23,118,2,1,44,43,42,116,49,50,51,109,58,94,15,55,70,56,103,52,61,57,108,47,46,16

},

lHUD = {

99,24,93,92,1,103,15,78,12,90,64,102,25,97,107,3,4,115,110,13,26,69,34,117,56,42,79,5,98,41,

113,27,59,33,108,58,43,77,86,74,40,94,28,30,32,84,51,44,95,68,114,39,65,29,50,31,121,106,45,6,

7,8,38,120,109,80,21,20,60,46,119,82,76,37,89,66,55,88,19,62,47,75,83,73,36,71,63,54,70,18,67,

48,91,101,87,35,49,52,53,104,17,11,96,111,16,9,112,23,100,72,57,118,10,61,14,116,2,105,22,81,85

};

//================================ end alphabets ==================================

 

char *storeAllocFail = "Storage allocation failed";

void reportError(char *msg) { printf("\a\nError: %s.\n", msg); }

// -----------

//---------------------------------------------------------------------------

 

void freeSquare(int*** square, int size) {

// ----------

if (*square != NULL) {

for (int i = 0; i < size; i++) free((*square)[i]);

free(*square); *square = NULL;

}

} // freeIntSquare

 

void freeQueue() { if (Queue != NULL) { free(Queue); Queue = NULL; } }

// ---------

 

void freeStore() {

// ---------

free(textLine); textLine = NULL;

freeSquare(&iSquare, allocatedSize);

freeSquare(&drainL, allocatedSize);

freeSquare(&drainR, allocatedSize);

freeSquare(&drainU, allocatedSize);

freeSquare(&drainD, allocatedSize);

freeSquare(&water, allocatedSize);

freeSquare(&oSquare, fontN*allocatedSize);

allocatedSize = 0;

free(numberUsed); numberUsed = NULL;

freeQueue();

} // freeStore

 

bool allocateSquare(int*** square, int size) {

// --------------

*square = (int**) malloc(size * sizeof(int*));

bool ok = (*square != NULL);

if (ok) {

int numAllocated = size;

for(int i = 0; i < size; i++) {

int *p = (int*) malloc(size * sizeof(int));

(*square)[i] = p;

if (p == NULL) { numAllocated = i; ok = false; break; }

}

if (!ok) freeSquare(square, numAllocated);

}

return ok;

} // allocateSquare

 

bool allocateQueue(int size)

// -------------

{

bool ok = true;

if (allocatedQueueSize < size) {

freeQueue();

Queue = (t_Cell *) malloc(size * sizeof(t_Cell));

if (ok = (Queue != NULL)) allocatedQueueSize = size;

}

return ok;

} // allocateQueue

 

bool increaseQueue()

// -------------

{

int size = allocatedQueueSize + allocatedQueueSize;

 

t_Cell *tmp = (t_Cell *) malloc(size * sizeof(t_Cell));

if (tmp == NULL) { reportError(storeAllocFail); return false; }

for (int i = 0; i < qIndex; i++) tmp[i] = Queue[i];

freeQueue(); Queue = tmp; allocatedQueueSize = size;

return true;

} // increaseQueue;

//---------------------------------------------------------------------------

 

bool allocateStore(int size) {

// -------------

bool ok = true;

if (size > allocatedSize) {

free(textLine); textLine = NULL;

freeSquare(&iSquare, allocatedSize);

freeSquare(&drainL, allocatedSize);

freeSquare(&drainR, allocatedSize);

freeSquare(&drainU, allocatedSize);

freeSquare(&drainD, allocatedSize);

freeSquare(&water, allocatedSize);

ok = ((textLine = (char *)malloc(size*sizeof(char))) != NULL);

if (ok) ok = allocateSquare(&iSquare, size);

if (ok) ok = allocateSquare(&drainL, size);

if (ok) ok = allocateSquare(&drainR, size);

if (ok) ok = allocateSquare(&drainU, size);

if (ok) ok = allocateSquare(&drainD, size);

if (ok) ok = allocateSquare(&water, size);

if (ok) ok = allocateQueue(size*size);

if (ok) allocatedSize = size;

}

if (ok) {

free(numberUsed);

ok = ((numberUsed = (bool *)malloc((size*size+1)*sizeof(bool))) != NULL);

}

if (ok) { ok = allocateSquare(&oSquare, fontN*size); } if (!ok) freeStore();

return ok;

} //allocateStore

//---------------------------------------------------------------------------

 

void initBounds(int n)

// ----------

{

int m = n-1;

for (int r = 0; r < n; r++) {

water[r][0] = iSquare[r][0];

water[r][m] = iSquare[r][m];

}

for (int c = 1; c < m; c++) {

water[0][c] = iSquare[0][c];

water[m][c] = iSquare[m][c];

}

 

for (int r = 1; r < m; r++) for (int c = 1; c < m; c++)

water[r][c] = maxNumber;

qIndex = 0;

} // initBounds

//---------------------------------------------------------------------------

 

void pushQueue(int priority, int row, int col)

// ---------

{

t_Cell cell; cell.priority = priority; cell.row = row; cell.col = col;

Queue[qIndex++] = cell;

} // pushQueue

 

bool insertQueue(int priority, int row, int col)

// -----------

{

if ((qIndex >= allocatedQueueSize) && !increaseQueue()) return false;

t_Cell cell; cell.priority = priority; cell.row = row; cell.col = col;

 

int i = qIndex-1;

while (Queue[i].priority < priority) {

Queue[i+1] = Queue[i]; if (--i < 0) break;

}

Queue[++i] = cell; ++qIndex; return true;

} // insertQueue

 

void popQueue(t_Cell *cell) { *cell = Queue[--qIndex]; }

// --------

//---------------------------------------------------------------------------

 

bool queueBorder(int m)

// -----------

{

pushQueue(water[1][0], 1, 0);

if (!insertQueue(water[1][m], 1, m)) return false;

 

for (int r = 2; r < m; r++) {

if (!insertQueue(water[r][0], r, 0)) return false;

if (!insertQueue(water[r][m], r, m)) return false;

}

 

for (int c = 1; c < m; c++) {

if (!insertQueue(water[0][c], 0, c)) return false;

if (!insertQueue(water[m][c], m, c)) return false;

}

return true;

} // queueBorder

//---------------------------------------------------------------------------

 

bool computeBounds(int p, int r, int c, int m)

// -------------

{

if ( ( (0 < r) && (r < (m)) ) && ( (0 < c) && (c < (m)) ) ) {

int *bp = &water[r][c], tmp = max(iSquare[r][c],p);

if (tmp < *bp) { *bp = tmp; if (!insertQueue(tmp, r, c)) return false; }

}

return true;

} // computeBounds

//---------------------------------------------------------------------------

 

/*

* Based on an algorithm of Gareth McCaughan supplied by Craig Knecht.

*/

bool getWater(int n)

// --------

{

int m = n-1; initBounds(n);

if (n > 1) {

if (!queueBorder(m)) return false;

while (qIndex != 0) {

t_Cell cell; popQueue(&cell);

int p = cell.priority, r = cell.row, c = cell.col;

if (!computeBounds(p, r-1, c, m)) return false;

if (!computeBounds(p, r+1, c, m)) return false;

if (!computeBounds(p, r, c-1, m)) return false;

if (!computeBounds(p, r, c+1, m)) return false;

}

}

return true;

} // getWater

//---------------------------------------------------------------------------

 

enum magicType { notMagic, otherMagic, normalMagic };

Uint MagicConstant; bool zeroBased;

magicType isMagic(int n) {

// -------

int **x = iSquare,

sumX, sumY, sumXY = 0, sumYX = 0, chkSum = 0, m = n - 1;

 

for (int i = 0; i < n; i++) {

sumX = 0; sumY = 0;

for (int j = 0; j < n; j++) {

sumX += x[i][j]; sumY += x[j][i];

}

if (i == 0) chkSum = sumX;

if ((sumX != chkSum) || (sumY != chkSum)) return notMagic;

sumXY += x[i][m - i]; sumYX += x[i][i];

}

if ((sumXY != chkSum) || (sumYX != chkSum)) return notMagic;

return otherMagic;

} // isMagic

 

magicType isNormal(int n) {

// --------

int **x = iSquare, min = zeroBased ? 0 : 1, max = n*n + min - 1, m = n-1,

chkSum = 0, sumX, sumY, sumXY = 0, sumYX = 0;

Uint magicConstant = MagicConstant;

 

if (zeroBased) magicConstant -= n;

for (int i = min; i <= max; i++) numberUsed[i] = false;

for (int i = 0; i < n; i++) {

sumX = 0; sumY = 0;

for (int j = 0; j < n; j++) {

int tmp = x[i][j]; numberUsed[tmp] = true;

sumX += tmp; sumY += x[j][i];

}

if (i == 0) chkSum = sumX;

if ((sumX != chkSum) || (sumY != chkSum)) return notMagic;

sumXY += x[i][m - i]; sumYX += x[i][i];

}

if ((sumXY != chkSum) || (sumYX != chkSum)) return notMagic;

if (chkSum != magicConstant) return otherMagic;

for (int i = min; i <= max; i++) if (!numberUsed[i]) return otherMagic;

return normalMagic;

} // isNormal

//---------------------------------------------------------------------------

 

int smallestRead = LONG_MAX, biggestRead = LONG_MIN;

int fieldWidth() { // including 1 space

// ----------

int fw, max12, tmp; bool neg = smallestRead < 0;

 

max12 = fontNN*smallestRead;

if (max12 < 0) max12 = -max12;

tmp = fontNN*biggestRead;

if (tmp < 0) tmp = -tmp; if (tmp > max12) max12 = tmp;

tmp = fontNN-1 + fontNN*smallestRead;

if (tmp < 0) tmp = -tmp; if (tmp > max12) max12 = tmp;

tmp = fontNN-1 + fontNN*biggestRead;

if (tmp < 0) tmp = -tmp; if (tmp > max12) max12 = tmp;

 

if (max12 <= 1) { fw = neg ? 3 : 2; }

else {

int i = max12, width = 1;

while ((i = i / 10) != 0) ++width; if (neg) ++width;

fw = width + 1;

}

return fw;

} // fieldWidth

 

//---------------------------------------------------------------------------

 

typedef bool (*t_fprintFW)(FILE *fp, int i);

 

bool fprintFW1(FILE *fp, int i) { return fprintf(fp, "%1d", i) > 0; }

bool fprintFW2(FILE *fp, int i) { return fprintf(fp, "%2d", i) > 0; }

bool fprintFW3(FILE *fp, int i) { return fprintf(fp, "%3d", i) > 0; }

bool fprintFW4(FILE *fp, int i) { return fprintf(fp, "%4d", i) > 0; }

bool fprintFW5(FILE *fp, int i) { return fprintf(fp, "%5d", i) > 0; }

bool fprintFW6(FILE *fp, int i) { return fprintf(fp, "%6d", i) > 0; }

bool fprintFW7(FILE *fp, int i) { return fprintf(fp, "%7d", i) > 0; }

bool fprintFW8(FILE *fp, int i) { return fprintf(fp, "%8d", i) > 0; }

bool fprintFW9(FILE *fp, int i) { return fprintf(fp, "%9d", i) > 0; }

bool fprintFWa(FILE *fp, int i) { return fprintf(fp, "%10d", i) > 0; }

bool fprintFWb(FILE *fp, int i) { return fprintf(fp, "%11d", i) > 0; }

 

static t_fprintFW fprintFW[] = {

NULL, fprintFW1, fprintFW2, fprintFW3, fprintFW4, fprintFW5,

fprintFW6, fprintFW7, fprintFW8, fprintFW9, fprintFWa, fprintFWb

};

const int maxFieldWidth = 11;

//----------------------------------------------------------------------

 

void zeroBase(int **x, int n) {

// --------

for (int r = 0; r < n; r++) for (int c = 0; c < n; c++) --x[r][c];

--smallestRead; -- biggestRead; zeroBased = true;

} // zeroBase

 

bool readError;

bool readSquare(FILE *rfp, int n, int **x, char *FName) {

// ----------

int smallest = LONG_MAX, biggest = LONG_MIN;

 

for (int r = 0; r < n; r++) {

for (int c = 0; c < n; c++) {

int tmp, rv;

 

if ( (rv = fscanf_s(rfp, "%d", &tmp)) == 1) {

if (tmp < smallest) smallest = tmp;

if (tmp > biggest) biggest = tmp;

x[r][c] = tmp;

} else {

if ( (rv != EOF) || (r != 0) || (c != 0) ) {

printf("\a\nError reading square from file %s\n", FName);

readError = true;

}

return false;

}

}

}

smallestRead = smallest; biggestRead = biggest;

zeroBased = smallestRead == 0;

if (!zeroBased) zeroBase(x, n);

return true;

} // readSquare

//---------------------------------------------------------------------------

 

void get_rest_of_line(int c) {

// ----------------

if (c != '\n') do { c = getchar(); } while (c != '\n');

}

 

bool getFileName(char *buf, int size) {

// -----------

int c, i = 0; char *s = buf;

 

do { c = getchar(); }

while ((c == ' ') || (c == '\t') || (c == '\n') ); *s = c;

while (i++ < size) if ( (*++s = getchar()) == '\n') break;

if (*s != '\n') {

printf("\nFile name too long.\n"); get_rest_of_line(*s); return false;

}

*s = '\0';

return true;

} // getFileName

//--------------------------------------------------------------------------

 

bool getY() {

// ----

int c; do { c = getchar(); } while ((c == ' ') || (c == '\t') || (c == '\n'));

get_rest_of_line(c); return (c == 'Y') || (c == 'y');

}

//--------------------------------------------------------------------------

 

const int bufSize = 1024, msgSize = bufSize + 100;

FILE *openInput(char *rFname) {

// ---------

char buf[bufSize];

sprintf_s(buf, bufSize, rFname); rFname = buf;

 

FILE *rfp = NULL; char *s = buf; bool txt = false;

while (*s++ != '\0');

while (--s != buf)

if (*s == '.') {

txt = (*++s == 't') && (*++s == 'x') && (*++s == 't') && (*++s == '\0');

break;

}

if (!txt) // no .txt entered, add it

strcat_s(buf, bufSize, ".txt");

if (fopen_s(&rfp, rFname, "r") != 0) {

char msg[msgSize];

sprintf_s(msg, msgSize, "\a\nCan't open for read %s", buf);

perror(msg); readError = true;

}

return rfp;

} // openInput

//--------------------------------------------------------------------------

 

char outputFileName[bufSize];

FILE *openOutput(int n1, int n2) {

// ----------

char buf[bufSize], defaultName[bufSize]; FILE *wfp = NULL; int sub = 0;

sprintf_s(defaultName, bufSize, "%d-%d-Composite", n1, n2);

sprintf_s(buf, bufSize, "%s.txt", defaultName);

do {

if (_access_s(buf, 00) == ENOENT)

break;

else

sprintf_s(buf, bufSize, "%s_%d.txt", defaultName, ++sub);

} while (true);

if (fopen_s(&wfp, buf, "w") == 0) {

sprintf_s(outputFileName, bufSize, buf);

printf("\nOutput order %d square file is %s\n", n1*n2, buf);

} else {

char msg[msgSize];

sprintf_s(msg, msgSize, "\a\nCan't open for write %s", buf);

perror(msg);

}

return wfp;

} // openOutput

//--------------------------------------------------------------------------

 

char iSquareFn[bufSize]; char *yesNo = "? y (yes) or n (no): ";

FILE *openInputFile(int which, int n) {

// -------------

char buf[bufSize], *rFname = NULL;

do {

if (which == 1) printf("\nYour order %d square file name? ", n);

else printf("\nText file name? ");

if (getFileName(buf, bufSize - 4)) { // reserve 4 to add .txt if needed

rFname = buf; break;

} else {

printf("\a\nCan't read the file name. Try again%s", yesNo);

if (!getY()) break;

}

} while (true);

if (which == 1) sprintf_s(iSquareFn, bufSize, buf);

if (rFname == NULL) return NULL; else return openInput(buf);

} // openInputFile

//--------------------------------------------------------------------------

 

bool checkSquare(int n, bool input) {

// -----------

magicType mt;

if ( (smallestRead < 0) || (biggestRead > n*n) )

mt = isMagic(n);

else {

mt = isNormal(n);

}

if ((mt == notMagic) || (mt == otherMagic)) {

if (input)

printf("The square %s is not %smagic.\n", iSquareFn,

mt == notMagic ? "" : "normal ");

else {

printf("\aProgram error: The default square is not normal magic.\n");

return false;

}

}

return true;

} // checkSquare

//--------------------------------------------------------------------------

 

void getNextLine(FILE *rfpT, int r) {

// -----------

int c = getc(rfpT);

for (int i = 0; i < lineLength; ++i) {

if (c == '\t') c = ' ';

if ((c == '\n') || (c == EOF)) textLine[i] = ' ';

else { textLine[i] = c; c = getc(rfpT); }

}

while ((c != '\n') && (c != EOF)) c = getc(rfpT);

} // getNextLine

 

int nextCh[fontN][fontN];

void getNextCh(FILE *rfpT, int i, int j) {

// ---------

if (j == 0) getNextLine(rfpT, i);

int c = textLine[j], k = 0; char *x = NULL;

 

if ( (c != ' ') && (water[i][j] > iSquare[i][j]))

printf("%c at row %d, col %d in water is not visible.\n", c, i+1, j+1);

 

if (drainL[i][j]) x = leftC[c];

else if (drainR[i][j]) x = rightC[c];

else if (drainU[i][j]) x = upC[c];

else x = downC[c];

 

if (c == 'h' || c == 'H') while (true) {

if (drainL[i][j]) {

if (drainR[i][j]) { x = lHLR; break; }

if (drainU[i][j]) { x = lHLU; break; }

if (drainD[i][j]) { x = lHLD; break; }

} else if (drainR[i][j]) {

if (drainU[i][j]) { x = lHRU; break; }

if (drainD[i][j]) { x = lHRD; break; }

} else if ((drainU[i][j]) && (drainD[i][j])) {

x = lHUD; break;

}

break;

}

if (x == NULL) {

printf("Character %c is not available; substituting a space.\n", c);

c = ' ';

if (drainL[i][j]) x = leftC[c];

else if (drainR[i][j]) x = rightC[c];

else if (drainU[i][j]) x = upC[c];

else x = downC[c];

}

for (int r = 0; r < fontN; ++r) for (int c = 0; c < fontN; ++c)

nextCh[r][c] = x[k++];

} // getNextCh

 

bool fileOutput;

bool outputSquare(FILE *wfp, int n, int fw) {

// ------------

int fw0 = fw - 1;

if (fw > maxFieldWidth) {

printf("Output format overflow.\n"); return false;

}

for (int r = 0; r < n; ++r) {

if (!fprintFW[fw0](wfp, oSquare[r][0])) return false;

for (int c = 1; c < n; ++c) {

if (!fprintFW[fw](wfp, oSquare[r][c])) return false;

}

if (fputc('\n', wfp) == EOF) return false;

}

return fputc('\n', wfp) != EOF;

} // outputSquare

 

void getDrainage(int n, int **x, int **w) {

// -----------

if (n == 1) {

drainL[0][0] = 1; drainR[0][0] = 1; drainU[0][0] = 1; drainD[0][0] = 1;

} else {

int m = n-1, l = m-1;

for (int r = 0; r < n; ++r) {

drainL[r][0] = 1; drainR[r][0] = (int)(x[r][0] > w[r][1]);

drainR[r][m] = 1; drainL[r][m] = (int)(x[r][m] > w[r][l]);

if (r > 0) {

drainU[r][0] = (int)(x[r][0] > w[r-1][0]);

drainU[r][m] = (int)(x[r][m] > w[r-1][m]);

}

if (r < m) {

drainD[r][0] = (int)(x[r][0] > w[r+1][0]);

drainD[r][m] = (int)(x[r][m] > w[r+1][m]);

}

}

for (int c = 0; c < n; ++c) {

drainU[0][c] = 1; drainD[0][c] = (int)(x[0][c] > w[1][c]);

drainD[m][c] = 1; drainU[m][c] = (int)(x[m][c] > w[l][c]);

if (c > 0) {

drainL[0][c] = (int)(x[0][c] > w[0][c-1]);

drainL[m][c] = (int)(x[m][c] > w[m][c-1]);

}

if (c < m) {

drainR[0][c] = (int)(x[0][c] > w[0][c+1]);

drainR[m][c] = (int)(x[m][c] > w[m][c+1]);

}

}

 

for (int r = 1; r < m; ++r) for (int c = 1; c < m; ++c) {

drainL[r][c] = (int)(x[r][c] > w[r][c-1]);

drainR[r][c] = (int)(x[r][c] > w[r][c+1]);

drainU[r][c] = (int)(x[r][c] > w[r-1][c]);

drainD[r][c] = (int)(x[r][c] > w[r+1][c]);

}

}

} // getDrainage

 

bool makeSquare(int n, FILE *rfpT, FILE *wfp)

// ----------

{

if (!getWater(n)) return true; // no write error

getDrainage(n, iSquare, water);

for (int i = 0; i < n; ++i) {

int ro = i*fontN;

for (int j = 0; j < n; ++j) {

int co = j*fontN;

getNextCh(rfpT, i, j);

for (int r = 0; r < fontN; ++r) for (int c = 0; c < fontN; ++c)

oSquare[r+ro][c+co] = nextCh[r][c]+fontNN*iSquare[i][j];

} // for (int j = 0

} // for (int i = 0

if (outputSquare(wfp, fontN*n, fieldWidth()))

return fileOutput = true;

return false;

} // makeSquare

//--------------------------------------------------------------------------

 

void getMagicConstant(int n) { MagicConstant = n * (n*n + 1) / 2; }

// -----------------

//--------------------------------------------------------------------------

 

void outputLocalTime() {

// --------------

time_t startTime = time(NULL); struct tm local;

if (localtime_s(&local, &startTime) == 0) {

char dateTime[100];

size_t slen = strftime(dateTime, 100, "%A %Y-%m-%d %X %Z\n\0", &local);

printf("\n%s", dateTime);

}

} // outputLocalTime

//--------------------------------------------------------------------------

 

bool validOrder(int n) {

// ----------

if (n <= 0) {

printf("\aError: Order %d is not a positive integer.\n", n); return false;

} else if (n == 2) {

printf("\aError: There is no magic square of order 2.\n"); return false;

} else return true;

}// validOrder

 

bool checkOrder(int n) {

// ----------

if (validOrder(n)) {

int mn = fontN*n, q = LONG_MAX / mn;

if ((mn < 0) || (mn > q)) {

printf("\aError: Integer overflow for (%d x %d) squared.\n", fontN, n);

return false;

}

return true;

}

return false;

}// checkOrder

//--------------------------------------------------------------------------

 

void printElapsedTime(time_t startTime) {

// ----------------

int et = (int)difftime(time(NULL), startTime);

if (et > 0)

printf("\nelapsed time %d:%02d:%02d\n", et/3600, et%3600/60, et%60);

} // printElapsedTime

//--------------------------------------------------------------------------

 

void checkContinue(bool *another) {

// -------------

if (*another) {

printf("\nContinue%s", yesNo); *another = getY();

}

} // checkContinue

//--------------------------------------------------------------------------

 

int textLineLength(FILE *rfpT) {

// --------------

const int maxN = bufSize; int lines = 0, longest = 0;

bool fileEnd = false;

 

while (!fileEnd) {

int l = 0; while (true) {

int c = getc(rfpT);

if ((c == '\n') || (c == EOF)) {

if (l > longest) longest = l;

if (c == EOF) { if (l==0) --lines; fileEnd = true; }

break;

}

++l;

}

++lines;

}

int n = max(lines,longest);

if (n > maxN) {

if (n == lines)

printf("\aError: Number of text lines limited to %d.\n", maxN);

else

printf("\aError: Text line limited to %d characters.\n", maxN);

n = 0;

} else if (n == 0)

printf("\aError: No text in file.\n");

else if (!checkOrder(n)) n = 0;

rewind(rfpT); return n;

} // textLineLength

//======================== start bordered square ===========================

 

void makeActual(int **x, int n) {

// ----------

int nn = n*n;

if (n&1) {

int midc = (nn + 1) / 2;

for (int i = 0; i < n; i++) for (int j = 0; j < n; j++)

x[i][j] += midc;

} else {

int pPlus = nn / 2, mPlus = pPlus + 1;

for (int i = 0; i < n; i++) for (int j = 0; j < n; j++)

x[i][j] += x[i][j] > 0 ? pPlus : mPlus;

}

} // makeActual

 

void makeEven(int **x, int size) {

// --------

int i, j, k, o, n, m, v = 1; // 0.5;

 

// fill center 4x4

o = (size - 4) / 2; k = o + 1; m = o + 2; n = o + 3;

x[m][k] = -v; x[m][m] = v++;

x[n][m] = -v; x[n][k] = v++;

x[n][n] = -v; x[n][o] = v++;

x[m][o] = -v; x[m][n] = v++;

x[o][m] = -v; x[o][k] = v++;

x[k][k] = -v; x[k][m] = v++;

x[k][o] = -v; x[k][n] = v++;

x[o][n] = -v; x[o][o] = v++;

for (i = 6; i <= size; i += 2) {

o = (size - i) / 2; n = o + i - 1; k = (o + n - 1) / 2; m = k + 1;

int tm = m-1, tp = o+1, lm = o+1, lp = m;

if (i % 4 != 0) { //------------------------------ // singly even

j = (k-o+1)/2; while (j--) {

x[o][tm] = -v; x[n][tm++] = v++;

x[n][tp] = -v; x[o][tp++] = v++;

}

x[o][tm] = -v; x[n][tm++] = v++;

x[lm][o] = -v; x[lm++][n] = v++;

j = (k-o-1)/2; while (j--) {

x[lp][n] = -v; x[lp++][o] = v++;

x[lm][o] = -v; x[lm++][n] = v++;

}

x[n][n] = -v; x[o][o] = v++; // NW

x[n][o] = -v; x[o][n] = v++; // NE

x[lp][n] = -v; x[lp++][o] = v++;

j = (n-m-1)/2; while (j--) {

x[lm][o] = -v; x[lm++][n] = v++;

x[lp][n] = -v; x[lp++][o] = v++;

}

x[lp][n] = -v; x[lp++][o] = v++;

x[o][tm] = -v; x[n][tm++] = v++;

j = (n-m-1)/2; while (j--) {

x[n][tp] = -v; x[o][tp++] = v++;

x[o][tm] = -v; x[n][tm++] = v++;

}

x[lm][o] = -v; x[lm][n] = v++;

} else { //--------------------------------------- // doubly even

x[o][tm] = -v; x[n][tm++] = v++;

j = (k-o)/2; while (j--) {

x[n][tp] = -v; x[o][tp++] = v++;

x[o][tm] = -v; x[n][tm++] = v++;

}

if (i == 8) {

x[lp][n] = -v; x[lp++][o] = v++;

} else {

x[lm][o] = -v; x[lm++][n] = v++;

x[lp][n] = -v; x[lp++][o] = v++;

j = (k-o-5)/2; while (j--) {

x[lm][o] = -v; x[lm++][n] = v++;

x[lp][n] = -v; x[lp++][o] = v++;

}

x[lp][n] = -v; x[lp++][o] = v++;

}

x[lm][o] = -v; x[lm++][n] = v++;

x[lm][o] = -v; x[lm++][n] = v++;

x[n][n] = -v; x[o][o] = v++; // NW

x[n][o] = -v; x[o][n] = v++; // NE

x[lp][n] = -v; x[lp++][o] = v++;

x[lp][n] = -v; x[lp++][o] = v++;

j = (n-m-2)/2; while (j--) {

x[lm][o] = -v; x[lm++][n] = v++;

x[lp][n] = -v; x[lp++][o] = v++;

}

x[k][o] = -v; x[k][n] = v++;

j = (n-m)/2; while (j--) {

x[o][tm] = -v; x[n][tm++] = v++;

x[n][tp] = -v; x[o][tp++] = v++;

}

x[o][tm] = -v; x[n][tm] = v++;

}

}

makeActual(x, size);

} // makeEven

//---------------------------------------------------------------------------

 

void makeOdd(int **x, int size) {

// -------

int i, j, o, n, m, v = 1;

 

m = (size - 1) / 2; x[m][m] = 0;

 

for (i = 3; i <= size; i += 2) {

o = (size - i) / 2; n = o + i - 1; m = (o + n) / 2;

 

for (j = o + 1; j < m; j++) {

x[n][j] = -v; x[o][j] = v++; // NNW

x[j][o] = -v; x[j][n] = v++; // ENE

}

x[n][o] = -v; x[o][n] = v++; // NE

x[m][o] = -v; x[m][n] = v++; // E

x[n][n] = -v; x[o][o] = v++; // NW

x[o][m] = -v; x[n][m] = v++; // S

for (j = m + 1; j < n; j++) {

x[o][j] = -v; x[n][j] = v++; // SSE

x[j][n] = -v; x[j][o] = v++; // WSW

}

}

makeActual(x, size);

} // makeOdd

//========================= end bordered square ===========================

 

bool getSquare(int n, FILE **rfpS) {

// ---------

printf("Use default square%s", yesNo); bool input = false;

if (getY()) {

if (n&1) makeOdd(iSquare, n); else makeEven(iSquare, n);

smallestRead = 1; biggestRead = n*n; zeroBase(iSquare, n);

} else {

*rfpS = openInputFile(1, n); if (*rfpS == NULL) return false;

if (!(readSquare(*rfpS, n, iSquare, iSquareFn))) return false;

input = true;

}

maxNumber = biggestRead; return checkSquare(n, input);

} // getSquare

//--------------------------------------------------------------------------

 

int main() {

// ----

bool another = true, writeError = false; outputLocalTime();

do {

FILE *rfpT = openInputFile(0, 0);

if (rfpT != NULL) {

int n = textLineLength(rfpT);

if (n > 0) {

getMagicConstant(n);

if (allocateStore(n)) {

FILE *rfpS = NULL;

if (getSquare(n, &rfpS)) {

FILE *wfp = openOutput(fontN, n);

if (wfp != NULL) {

time_t startTime = time(NULL);

fileOutput = false; lineLength = n;

writeError = !makeSquare(n, rfpT, wfp);

fclose(wfp); if (!fileOutput) remove(outputFileName);

printElapsedTime(startTime);

}

} // if (getSquare

if (rfpS != NULL) fclose(rfpS);

} else {

printf("\a\nError: Storage allocation failed.\n");

} // if (allocateStore(n)

} // if (n > 0)

fclose(rfpT);

} // if (rfpT != NULL)

if (writeError) {

perror("\a\nError writing file"); another = false;

}

checkContinue(&another);

} while (another);

 

freeStore();

printf("\nPress a key to close the console.");

while (!_kbhit()) Sleep(250);

return 0;

} // main