Oxygene for Java version of Crossword

Pascal version by Adam Renak: L6 Age ~16

Introduction

See above a description of the Pascal file and the link for the download of the dictionary text file. In the conversion to Oxygene for Java, note the following points.
  • Arrays are zero based.
  • Individual characters in strings are accessed like an array of char, but in Oxygene are zero based.
  • Oxygene, like Pascal, uses nil instead of Java's null.
  • Variables are objects and have useful methods such as toString for an Integer and trim (to strip spaces from a string).
  • Read becomes System.in.read. We read an array of SByte first, convert this to a string, then trim the trailing spaces.
  • Reading lines from a file is achieved using 3 objects: a FileInputStream, an InputStreamReader and a LineNumberReader.
  • Procedures and functions become methods (although the original terminology is accepted).

We typed at the Command Prompt cd c:\Oxygene to change the current directory to our project folder. We compiled the program with the command msbuild crossword.oxygene and executed the contents of the resultant jar file with the command java -jar bin\Release\crossword.jar You can open the project file in Visual Studio and execute the program with a click on the green triangle.

The program in crossword.pas

namespace Crossword;
{
    Copyright (c) 2010 Adam Renak

    Licensed under the Apache License, Version 2.0 (the "License"); you may
    not  use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/

    Converted to Oxygene for Java by PPS (2013)
}
interface

uses
  java.io.*;

var
  Words, NarrowWords : Array[0 .. 100000] of string;
  word_length : Integer;
  Narrowfactor : Integer := -1;
  const ListLength = 80368;

implementation

method LoadWordlist;
var
  fis : FileInputStream;
  isr : InputStreamReader;
  lnr : LineNumberReader;
  Count : Integer := -1;
begin 
  fis := new FileInputStream('DictWordlist.txt');
  isr := new InputStreamReader(fis);
  lnr := new LineNumberReader(isr);
  repeat
    inc(Count);
    Words[Count] := lnr.readLine;   
  until Words[Count] = nil;
  fis.close;  
end;

//Narrows the wordlist down to words of similar length
method NarrowLength;                                     
var
  Count1, Count2 : Integer;
begin  
  Count2 := -1;
  for Count1 := 0 to ListLength - 1 do
    begin
      if word_length = length(words[Count1]) then
        begin
          inc(Count2);
          Narrowwords[Count2] := words[Count1];
          Narrowfactor := Count2; //Now Narrowfactor is zero based
        end;
    end;
end;

//Narrows list according to character position.
method Narrow(vWord : string; position : integer);                 
var
  NarrowPos, InsertCount : Integer;
begin
  InsertCount := -1; //Sets the pointer that the new narrowlist begins at.
  for NarrowPos := 0 to Narrowfactor  do //From 0 to last narrowed word
    if (vWord[position] = narrowwords[NarrowPos][position]) then
      begin
        Inc(InsertCount);
        NarrowWords[InsertCount] := Narrowwords[NarrowPos];
      end;
    Narrowfactor := InsertCount; //Reduces the Narrowfactor 
end;

var  
  CharPosn, writecount : Integer;
  input_word : array[0 .. 20] of SByte;
  input_string, lower_case_string, lower_case_word : string;
begin
  Loadwordlist;
  repeat
    writeln('Input the word to solve. Use ? to show unknowns:');
    input_word := [32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32];
    System.in.read(input_word);
    input_string := new string(input_word);
    lower_case_string := input_string.toLowerCase; 
    lower_case_word := lower_case_string.trim; //Removes trailing spaces
    word_length := length(lower_case_word);
    Narrowlength;
    for CharPosn := 0 to word_length - 1 do  //Zero based chars in string  
      if lower_case_word[CharPosn] <> '?' then
        Narrow(lower_case_word, CharPosn);
    //Write a list of matching words:
    writeln('--------------------------------------');
    for WriteCount := 0 to Narrowfactor do //Writes possible words    
      writeln('MATCH: ' + NarrowWords[WriteCount].toString); 
    //If no match is found, it writes the five closest matches.
    if Narrowfactor = -1 then  
      begin
        writeln('No match found. Try these suggestions:');
        writeln;
        for WriteCount := (Narrowfactor + 1) to (Narrowfactor + 6) do 
          writeln(NarrowWords[WriteCount].toString);    
      end; 
    writeln('--------------------------------------');
    writeln; 
    Thread.sleep(1000);
  until lower_case_word = 'end';
end.

The project file crossword.oxygene

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProductVersion>3.5</ProductVersion>
    <OutputType>Exe</OutputType>
    <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
    <Name>Crossword</Name>
    <RootNamespace>org.me.crossword</RootNamespace>    
    <AssemblyName>crossword</AssemblyName>
    <StartupClass />
    <DefaultUses />
  </PropertyGroup>  
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <Optimize>true</Optimize>
    <OutputPath>.\bin\Release</OutputPath>
    <GenerateDebugInfo>False</GenerateDebugInfo>
    <GenerateMDB>False</GenerateMDB>
    <EnableAsserts>False</EnableAsserts>
    <TreatWarningsAsErrors>False</TreatWarningsAsErrors>
    <CaptureConsoleOutput>False</CaptureConsoleOutput>
    <StartMode>Project</StartMode>
    <RegisterForComInterop>False</RegisterForComInterop>
    <CpuType>anycpu</CpuType>
    <RuntimeVersion>v25</RuntimeVersion>
    <XmlDoc>False</XmlDoc>
    <XmlDocWarningLevel>WarningOnPublicMembers</XmlDocWarningLevel>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="rt.jar" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="crossword.pas">
      <SubType>Code</SubType>
    </Compile>
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Oxygene\RemObjects.Oxygene.Cooper.targets" />
</Project>
Programming - a skill for life!

by Adam Renak: L6 Age ~16