Пример #1
0
        public bool _canTheseOrthogonalVectorsExistTogether(WordVector horiz, WordVector vert)
        {
            //this code is non obvious, NOTE:
            // A) orthogonal vectors often intersect. They are supposed to in a crossword
            // B) All intersections (letters are equal) are already approved.

            switch (Othogonal_Rule)
            {
            case WordPlacement_Othogonal_Rules.CanTouch:
                return(true);

            case WordPlacement_Othogonal_Rules.NoTouch:
                //also this statements are non obvious (looks wrong) till you do the working out
                if ((horiz.Y >= vert.Y) && (horiz.Y <= vert.LastY))
                {
                    return(((horiz.X + horiz.Length) != vert.X) &&
                           (horiz.X != (vert.X + 1)));
                }

                if ((vert.X >= horiz.X) && (vert.X <= horiz.LastX))
                {
                    return(((vert.Y + vert.Length) != horiz.Y) &&
                           (vert.Y != (horiz.Y + 1)));
                }

                return(true);

            default:
                return(true);
            }
        }
Пример #2
0
        private List <Tuple <WordVector, int> > GetPossibleVectors(string text)
        {
            List <Dir2D> dirs = new List <Dir2D>()
            {
                Dir2D.Right, Dir2D.Down
            };

            List <Tuple <WordVector, int> > possibleVecs = new List <Tuple <WordVector, int> >();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    foreach (Dir2D dir in dirs)
                    {
                        WordVector vec = new WordVector(new Point(x, y), dir, text.Length);

                        int intersectionCount = testPlacement(text, vec);

                        if (intersectionCount > 0)
                        {
                            possibleVecs.Add(new Tuple <WordVector, int>(vec, intersectionCount));
                        }
                    }
                }
            }

            return(possibleVecs);
        }
Пример #3
0
        private int testPlacement(string text, WordVector vec)
        {
            bool ok = true;
            int  intersectionCount = 0;

            if ((vec.LastX >= Width) || (vec.LastX < 0) || (vec.LastY >= Height) || (vec.LastY < 0))
            {
                return(0); //placement leaves grid
            }

            Point pos = vec.Pos;

            for (int i = 0; i < vec.Length; i++)
            {
                char?charGrid = grid[pos.X, pos.Y];
                char charText = text[i];
                if (charGrid != null)
                {
                    if (charGrid.Value == charText)
                    {
                        intersectionCount++;
                    }
                    else
                    {
                        ok = false;
                        break;
                    }
                }

                //next pos
                pos = pos.NextPoint(vec.Dir);
            }

            return(ok ? intersectionCount : 0);
        }
Пример #4
0
        /// <summary>
        /// Assigns 1 across etc
        /// </summary>
        private void AssignIndexes()
        {
            var acrossWords = from wrd in Words
                              where (wrd.Dir == Dir2D.Right)
                              orderby wrd.Pos.Y, wrd.Pos.X
            select wrd;

            var downWords = from wrd in Words
                            where (wrd.Dir == Dir2D.Down)
                            orderby wrd.Pos.Y, wrd.Pos.X
            select wrd;

            int i = 1;

            foreach (WordVector wv in acrossWords)
            {
                wv.IndexValue = i;
                i++;
            }

            foreach (WordVector wv in downWords)
            {
                WordVector other = acrossWords.FirstOrDefault(W => W.Pos == wv.Pos);
                if (other == null)
                {
                    wv.IndexValue = i;
                    i++;
                }
                else
                {
                    wv.IndexValue = other.IndexValue; //ie 15 across..., 15 down...
                }
            }
        }
Пример #5
0
        public static bool VectorHasLetters(this IWordGrid g, WordVector vec)
        {
            Point p = vec.Pos;

            for (int i = 0; i < vec.Length; i++)
            {
                if (g[p] == null)
                {
                    return(false);
                }

                p = p.NextPoint(vec.Dir);
            }

            return(true);
        }
Пример #6
0
        public static void placeWord(this IWordGrid g, string text, WordVector vec)
        {
            if (vec.Dir == Dir2D.None)
            {
                return;
            }

            Point p   = vec.Pos;
            int   len = 0;

            while (g.InBounds(p) &&
                   (len < vec.Length))
            {
                g[p] = text[len];
                len++;
                p = p.NextPoint(vec.Dir);
            }
        }
Пример #7
0
 public bool canTheseTwoVectorsExistTogether(WordVector a, WordVector b)
 {
     if (a.isVertical && b.isVertical)
     {
         return(_canTheseHorizontalVectorsExistTogether(Transpose(a), Transpose(b)));
     }
     else if (a.isHorizontal && b.isHorizontal)
     {
         return(_canTheseHorizontalVectorsExistTogether(a, b));
     }
     else if (a.isHorizontal && b.isVertical)
     {
         return(_canTheseOrthogonalVectorsExistTogether(a, b));
     }
     else
     {
         return(_canTheseOrthogonalVectorsExistTogether(b, a));
     }
 }
Пример #8
0
        public static string GetWord(this IWordGrid g, WordVector vec)
        {
            if (vec.Dir == Dir2D.None)
            {
                return(null);
            }

            Point  p   = vec.Pos;
            int    len = 0;
            string str = "";

            while (g.InBounds(p) && (g[p] != null) && (len < vec.Length))
            {
                str = str + g[p].Value;
                len++;
                p = p.NextPoint(vec.Dir);
            }

            return((len == vec.Length) ? str : null);
        }
Пример #9
0
        /// <summary>
        /// Can this word be placed along the vector with out altering any existing letters?
        /// </summary>
        /// <param name="vec"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool AnyConflicts(this IWordGrid g, WordVector vec, string str)
        {
            if (vec.Dir == Dir2D.None)
            {
                return(true);
            }

            Point p   = vec.Pos;
            int   len = 0;

            while (g.InBounds(p) &&
                   (len < vec.Length) &&
                   isSameLetterOrNull(g[p], str[len])
                   )
            {
                len++;
                p = p.NextPoint(vec.Dir);
            }

            return((len - 1) == vec.Length);
        }
Пример #10
0
        internal bool Intersects(WordVector other)
        {
            //TODO: simple algorithm, needs to be replaced with something more efficient
            Point p = Pos;

            for (int i = 0; i < Length; i++)
            {
                if (other.Intersects(p))
                {
                    return(true);
                }

                p = p.NextPoint(Dir);
            }
            return(false);

            /*
             * if(this.Dir == Dir2D.None) {
             *  return other.Intersects(this.Pos);
             * }
             * else if(other.Dir == Dir2D.None) {
             *  return this.Intersects(other.Pos);
             * }
             * else if(isHorizontal(this.Dir))
             * {
             *  if(isHorizontal(other.Dir))
             *  {
             *      //Range.
             *  }
             *  else
             *  {
             *  }
             * }
             * else //this is vertical
             * {
             * }
             */
        }
Пример #11
0
 private WordVector Transpose(WordVector v)
 {
     return(new WordVector(new Point(v.Pos.Y, v.Pos.X), otherDir(v.Dir), v.Length));
 }
Пример #12
0
        public bool _canTheseHorizontalVectorsExistTogether(WordVector _a, WordVector _b)
        {
            //check this to eliminate many checks later
            if ((Parallel_Rule == WordPlacement_Parallel_Rules.EvenLinesOnly) &&
                (((_a.Y % 2) == 1) || ((_b.Y % 2) == 1)))
            {
                return(false);
            }

            //a is the left most
            bool       swap = (_a.Pos.X > _b.Pos.X);
            WordVector a    = swap ? _b : _a;
            WordVector b    = swap ? _a : _b;

            RangeInt aRange = RangeInt.FromStartAndLength(a.Pos.X, a.Length);
            RangeInt bRange = RangeInt.FromStartAndLength(b.Pos.X, b.Length);

            //rule out vectors not near each other to eliminate many checks later
            RangeInt aRangePlus = RangeInt.FromStartAndLength(a.Pos.X, a.Length + 1);
            RangeInt bRangePlus = RangeInt.FromStartAndLength(b.Pos.X, b.Length + 1);

            if (!aRangePlus.Intersects(bRangePlus))
            {
                return(true); //no reason to test
            }

            if (a.Pos.Y == b.Pos.Y)
            {
                //run on rules apply
                switch (RunOnRule)
                {
                case WordPlacement_RunOn_Rules.NoRestrictions:
                    return(true);

                case WordPlacement_RunOn_Rules.NoContainment:
                    return(!(aRange.Contains(bRange) || bRange.Contains(aRange)));

                case WordPlacement_RunOn_Rules.NoRunOnOverLap:
                    return(!aRange.Intersects(bRange));

                case WordPlacement_RunOn_Rules.NoRunOnTouching:
                    return(false);     //because of previous tests we know they must at least but together

                default:
                    throw new InvalidOperationException();
                }
            }
            else if (Math.Abs(a.Pos.Y - b.Pos.Y) == 1)
            {
                //parallel rules apply
                switch (Parallel_Rule)
                {
                case WordPlacement_Parallel_Rules.NoRestrictions:
                    return(true);

                case WordPlacement_Parallel_Rules.MustHaveGap:
                    return(false);

                case WordPlacement_Parallel_Rules.EvenLinesOnly:
                    return(true);    //previous testing has already solved the case for false

                default:
                    throw new InvalidOperationException();
                }
            }
            else
            {
                //they are not near each other vertically
                return(true);
            }
        }
Пример #13
0
        //----------------------------------------------------------------------------------
        // Creating crosswords
        //----------------------------------------------------------------------------------
        public void Generate(LanguageDictionary dictionary, int seed = -1)
        {
            int maxWords = TargetWordCount;

            seeedRandomGenerator(seed);
            this.Dictionary = dictionary;
            //start with a long word

            Word       word = getNextWord(maxWords);
            string     text = word.PrimarySpelling.ToLower();
            WordVector vec  = new WordVector(new Point(roundUpTillEven((Width - text.Length) / 2),
                                                       roundUpTillEven(Height / 2)),
                                             Dir2D.Right,
                                             text.Length);

            vec.Word = word;
            grid.placeWord(text, vec);
            addUsedWord(text);
            this.words.Add(vec);
            dump(words);

            int esc = 0;

            //place Word
            while ((WordCount < maxWords) && (word != null))
            {
                word = getNextWord(maxWords);
                if (word == null)
                {
                    break; //done
                }

                //temp, escape
                esc++;
                if (esc > 10000)
                {
                    break;
                }

                text = word.PrimarySpelling.ToLower();

                List <Tuple <WordVector, int> > possibleVecs = GetPossibleVectors(text);

                //remove any rule violations
                possibleVecs = possibleVecs.Where(V => !this.Words.Any(N => !canTheseTwoVectorsExistTogether(N, V.Item1))).ToList();

                if (possibleVecs.Count > 0)
                {
                    //we want the most intersectiony option
                    int maxIntersects = possibleVecs.Max(V => V.Item2);
                    possibleVecs = possibleVecs.Where(V => V.Item2 == maxIntersects).ToList();

                    vec      = possibleVecs.GetRandomItem(rnd).Item1;
                    vec.Word = word;
                    grid.placeWord(text, vec);
                    addUsedWord(text);
                    this.words.Add(vec);
                    dump(words);

                    esc = 0;
                }
            }

            //finish up the related tasks
            AssignIndexes();
        }
Пример #14
0
        private List <WordVector> GetPossibleVectors_old(string text)
        {
            List <WordVector> possibleVecs = new List <WordVector>();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //is there a character at the grid which matches our text
                    char?_c = grid[x, y];
                    if ((_c != null) && (text.Contains(_c.Value)))
                    {
                        List <WordVector> interSectingVecsToCurrentGridPoint = (from v in Words where v.Intersects(x, y) select v).ToList();

                        //only one word should intersect this letter (so far)
                        //we are trying to place this word orthogonally across it
                        if (interSectingVecsToCurrentGridPoint.Count == 1)
                        {
                            WordVector intersect        = interSectingVecsToCurrentGridPoint[0];
                            Dir2D      newDir           = otherDir(intersect.Dir);
                            Dir2D      newDirOrthogonal = intersect.Dir;

                            //check all possible intersection points
                            foreach (int pos in text.IndexOfAll(_c.Value))
                            {
                                //create the vector that would position the word orthogonally across the other
                                WordVector newVec;
                                if (newDir == Dir2D.Down)
                                {
                                    newVec = new WordVector(new Point(x, y - pos), newDir, text.Length);
                                }
                                else //across
                                {
                                    newVec = new WordVector(new Point(x - pos, y), newDir, text.Length);
                                }

                                //check it works (does not put a different letter on top of another word)
                                if (!this.grid.AnyConflicts(newVec, text))
                                {
                                    if (words.TrueForAll(W => canTheseTwoVectorsExistTogether(W, newVec)))
                                    {
                                        possibleVecs.Add(newVec);
                                    }


                                    /*
                                     * //get the orthogonal words intersected
                                     * List<WordVector> interSectingVecsToNewVec = (from v in Words where v.Intersects(newVec) select v).ToList();
                                     *
                                     * //can't intersect another WordVector in the same direction
                                     * if (interSectingVecsToNewVec.TrueForAll(V => V.Dir == newDirOrthogonal))
                                     * {
                                     *  //the word should not impinge on exclusion zones of the existing vectors
                                     *  //other than the one it intersects orthogonally to
                                     *  List<WordVector> nonIntersectingVectors = Words.Where(V => !interSectingVecsToNewVec.Contains(V)).ToList();
                                     *
                                     *  if (nonIntersectingVectors.TrueForAll(V => !(newVec.InCrosswordStyleExclusionZoneOF(V))))
                                     *  {
                                     *      possibleVecs.Add(newVec);
                                     *  }
                                     * }*/
                                }
                            }
                        }
                    }
                }
            }

            //done
            return(possibleVecs);
        }
Пример #15
0
 protected WordVector(WordVector other)
 {
     this.Pos    = other.Pos;
     this.Dir    = other.Dir;
     this.Length = other.Length;
 }