-- Inequalities.mesa -- Edited by Sweet, 21-Jan-81 21:40:58 DIRECTORY Ascii, Inline, IODefs, PressDefs, PressUtilities, Random, String; Inequalities: PROGRAM IMPORTS Inline, IODefs, PressDefs, PressUtilities, Random, String = BEGIN OPEN PressDefs; pfdBody: PressFileDescriptor; pfd: POINTER TO PressFileDescriptor = @pfdBody; Mica: TYPE = CARDINAL; MBox: TYPE = RECORD [x,y,w,h: Mica]; LineWidth: Mica _ 30; CharHeight: Mica; CharWidth: POINTER TO ARRAY CHARACTER OF Mica; TextCharWidth: ARRAY CHARACTER OF Mica; AnswerCharWidth: ARRAY CHARACTER OF Mica; TextCharHeight: Mica; AnswerCharHeight: Mica; Minus: CHARACTER = Ascii.ControlX; answers: BOOLEAN _ FALSE; PointsToMicas: PROC [points: CARDINAL] RETURNS [Mica] = {RETURN [Inline.LongDiv[Inline.LongMult[points, MicasPerInch],72]]}; maxValue: CARDINAL _ 10; Prob: TYPE = RECORD [a,b: [0..16)]; HistSize: CARDINAL = 8; history: ARRAY [0..HistSize) OF Prob _ ALL[[0,0]]; hp: CARDINAL _ 0; Problem: PROC RETURNS [a,b: CARDINAL] = BEGIN trial: Prob; DO trial _ TrialProblem[]; FOR i: CARDINAL IN [0..HistSize) DO IF history[i] = trial THEN EXIT; REPEAT FINISHED => GO TO ok; ENDLOOP; REPEAT ok => NULL; ENDLOOP; history[hp] _ trial; hp _ (hp+1) MOD HistSize; RETURN [trial.a, trial.b]; END; TrialProblem: PROC RETURNS [trial: Prob] = BEGIN trial.a _ Random.InRange[0, maxValue]; DO trial.b _ Random.InRange[0, maxValue]; IF trial.b # trial.a THEN EXIT; ENDLOOP; END; StringWidth: PROC [s: STRING] RETURNS [l: Mica] = BEGIN l _ 0; FOR i: CARDINAL IN [0..s.length) DO l _ l + CharWidth[s[i]]; ENDLOOP; END; LineY: PROC [box: POINTER TO MBox, line, of: CARDINAL, lead: Mica _ 0] RETURNS [Mica] = BEGIN h: Mica = CharHeight; bottom: Mica = (box.h- of*h - (of-1)*lead)/2; RETURN [box.y + bottom + (line-1)*(h+lead)]; END; CenterLine: PROC [s: STRING, box: POINTER TO MBox, line, of: CARDINAL _ 1, lead: Mica _ 0] = BEGIN w: Mica = StringWidth[s]; y: Mica = LineY[box: box, line: line, of: of, lead: lead] + P3; x: Mica = box.x + (box.w - w)/2; PutText[pfd, s, x, y]; END; RJLine: PROC [s: STRING, box: POINTER TO MBox, line, of: CARDINAL _ 1, lead: Mica _ 0] = BEGIN w: Mica = StringWidth[s]; y: Mica = LineY[box: box, line: line, of: of, lead: lead] + P3; x: Mica = box.x + (box.w - w); PutText[pfd, s, x, y]; END; LJLine: PROC [s: STRING, box: POINTER TO MBox, line, of: CARDINAL _ 1, lead: Mica _ 0] = BEGIN y: Mica = LineY[box: box, line: line, of: of, lead: lead] + P3; PutText[pfd, s, box.x, y]; END; DrawBorder: PROC [box: POINTER TO MBox] = BEGIN PutRectangle[p: pfd, xstart: box.x, ystart: box.y, xlen: box.w + LineWidth, ylen: LineWidth]; PutRectangle[p: pfd, xstart: box.x, ystart: box.y, xlen: LineWidth, ylen: box.h]; PutRectangle[p: pfd, xstart: box.x + box.w, ystart: box.y, xlen: LineWidth, ylen: box.h]; PutRectangle[p: pfd, xstart: box.x, ystart: box.y + box.h, xlen: box.w + LineWidth, ylen: LineWidth]; END; FillOpInequality: PROC [x,y: Mica] RETURNS [Mica] = BEGIN ns: STRING _ [2]; box: MBox; a,b: CARDINAL; yBase: Mica = y - M38; TextFont[]; [a, b] _ Problem[]; box _ [x: x, y: yBase, w: M38, h: M38]; CenterNum[a, @box]; box.x _ box.x + M38; DrawBorder[@box]; IF answers THEN CenterLine[(IF a < b THEN "<"L ELSE ">"), @box]; box.x _ box.x + M38; CenterNum[b, @box]; RETURN[y - M34]; END; ChoiceInequality: PROC [x,y: Mica] RETURNS [Mica] = BEGIN ns: STRING _ [2]; box: MBox; a,b: CARDINAL; yBase: Mica = y - M38; less: BOOLEAN = (Random.InRange[0,1] = 0); upper: BOOLEAN; TextFont[]; [a, b] _ Problem[]; upper _ less = (a < b); box _ [x: x, y: yBase, w: M38, h: M38]; RJNum[a, @box]; box.x _ box.x + M38; CenterLine[IF less THEN "<"L ELSE ">"L, @box]; box.x _ box.x + M38; LJNum[b, @box]; box _ [x: x, y: yBase - M38, w: M38, h: M38]; RJNum[a, @box]; box.x _ box.x + M38; CenterLine[IF less THEN ">"L ELSE "<"L, @box]; box.x _ box.x + M38; LJNum[b, @box]; IF answers THEN { box _ [x: x, y: (IF upper THEN yBase ELSE yBase-M38), w: 3*M38, h: M38]; DrawBorder[@box]}; RETURN[y - M34 - M14]; END; FillNumberInequality: PROC [x,y: Mica] RETURNS [Mica] = BEGIN ns: STRING _ [2]; box: MBox; a,b: CARDINAL; less: BOOLEAN = (Random.InRange[0,1] = 0); TextFont[]; [a, b] _ Problem[]; box _ [x: x + M38, y: y-M38, w: M38, h: M38]; DrawBorder[@box]; CenterNum[a, @box]; box.y _ box.y - M38 - P2; DrawBorder[@box]; CenterNum[b, @box]; box.x _ x; box.y _ box.y - M38 - P2; PutRectangle[p: pfd, xstart: box.x, ystart: box.y, xlen: M38, ylen: P1]; IF answers THEN { AnswerFont[]; CenterNum[(IF less THEN MIN[a,b] ELSE MAX[a,b]), @box]; TextFont[]}; box.x _ box.x + M38; CenterLine[(IF less THEN "<"L ELSE ">"L), @box]; box.x _ box.x + M38; PutRectangle[p: pfd, xstart: box.x, ystart: box.y, xlen: M38, ylen: P1]; IF answers THEN { AnswerFont[]; CenterNum[(IF less THEN MAX[a,b] ELSE MIN[a,b]), @box]; TextFont[]}; RETURN[y - 2*M34 - P2]; END; P1: Mica = PointsToMicas[1]; P2: Mica = PointsToMicas[2]; P3: Mica = PointsToMicas[3]; M1: Mica = MicasPerInch; M12: Mica = MicasPerInch/2; M14: Mica = MicasPerInch/4; M18: Mica = MicasPerInch/8; M34: Mica = (3*MicasPerInch)/4; M38: Mica = (3*MicasPerInch)/8; CenterNum: PROC [n: CARDINAL, box: POINTER TO MBox] = BEGIN w: Mica; ns: STRING _ [2]; String.AppendDecimal[ns, n]; w _ StringWidth[ns]; PutText[pfd, ns, box.x + (box.w-w)/2, box.y + P3 + (box.h-CharHeight)/2]; END; LJNum: PROC [n: CARDINAL, box: POINTER TO MBox] = BEGIN ns: STRING _ [2]; String.AppendDecimal[ns, n]; LJLine[ns, box]; END; RJNum: PROC [n: CARDINAL, box: POINTER TO MBox] = BEGIN ns: STRING _ [2]; String.AppendDecimal[ns, n]; RJLine[ns, box]; END; CenterChar: PROC [c: CHARACTER, box: POINTER TO MBox] = BEGIN w: Mica; ns: STRING _ [2]; ns.length _ 1; ns[0] _ c; w _ StringWidth[ns]; PutText[pfd, ns, box.x + (box.w-w)/2, box.y + P3 + (box.h-CharHeight)/2]; END; TextFont: PROC = BEGIN SetFont[p: pfd, Name: "Helvetica", PointSize: 18, Face: 2]; CharHeight _ TextCharHeight; CharWidth _ @TextCharWidth; END; AnswerFont: PROC = BEGIN SetFont[p: pfd, Name: "Helvetica", PointSize: 14, Face: 1]; CharHeight _ AnswerCharHeight; CharWidth _ @AnswerCharWidth; END; DigestFonts: PROC = BEGIN [] _ PressUtilities.FindFontWidths[ family: "Helvetica"L, points: 18, weight: bold, slope: regular, widths: LOOPHOLE[@TextCharWidth]]; TextCharHeight _ PointsToMicas[18]; [] _ PressUtilities.FindFontWidths[ family: "Helvetica"L, points: 14, weight: medium, slope: italic, widths: LOOPHOLE[@AnswerCharWidth]]; AnswerCharHeight _ PointsToMicas[14]; END; DoPage: PROC = BEGIN x, y, nexty: Mica; x _ M1; y _ 10*M1; AnswerFont[]; PutText[pfd, "Complete the number sentences with < or >."L, M1, y]; y _ y - M14; THROUGH [0..3) DO x _ M1 + M14; THROUGH [0..4) DO nexty _ FillOpInequality[x, y]; x _ x + M1 + M18 + M12; ENDLOOP; y _ nexty; ENDLOOP; PutRectangle[p: pfd, xstart: M1, ystart: y, xlen: 6*M1+M12, ylen: LineWidth]; y _ y - M14; AnswerFont[]; PutText[pfd, "Complete the number sentences."L, M1, y]; y _ y - M14; THROUGH [0..2) DO x _ M1 + M14; THROUGH [0..4) DO nexty _ FillNumberInequality[x, y]; x _ x + M1 + M18 + M12; ENDLOOP; y _ nexty; ENDLOOP; PutRectangle[p: pfd, xstart: M1, ystart: y, xlen: 6*M1+M12, ylen: LineWidth]; y _ y - M14; AnswerFont[]; PutText[pfd, "Circle the true number sentences."L, M1, y]; y _ y - M14; THROUGH [0..3) DO x _ M1 + M14; THROUGH [0..4) DO nexty _ ChoiceInequality[x, y]; x _ x + M1 + M18 + M12; ENDLOOP; y _ nexty; ENDLOOP; WritePage[pfd]; END; Driver: PROC = BEGIN state: Random.State; BEGIN OPEN IODefs; WriteString["max: "L]; maxValue _ ReadNumber[maxValue, 10]; WriteChar[CR]; END; DigestFonts[]; InitPressFileDescriptor[pfd, "Math.drill"L]; answers _ FALSE; Random.ReadState[@state]; THROUGH [0..3) DO DoPage[]; ENDLOOP; ClosePressFile[pfd]; Random.WriteState[@state]; history _ ALL[[0,0]]; InitPressFileDescriptor[pfd, "Math.key"L]; answers _ TRUE; THROUGH [0..3) DO DoPage[]; ENDLOOP; ClosePressFile[pfd]; END; Driver[]; END.