• Stars
    star
    49
  • Rank 585,874 (Top 12 %)
  • Language
    C++
  • License
    MIT License
  • Created over 5 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Port of Python's Turtle to C++


C-Turtle is a port of Python's Turtle facility for C++11, with the intent of being a close analog to the Python implementation. This package was developed with the intent of student usage under an academic setting, and was designed to be "as easy to use as possible". This package has been released under the MIT license accordingly. Given that this is intended to be an education-oriented package, to ease the setup process it has been created to be Header-Only. Simply copy CTurtle.hpp (alongside CImg.hpp) into your include path or project and you're ready to go.

This package heavily uses CImg for its display and drawing functions. As such, it must be available in the include path alongside CTurtle itself.

Is it "C-Turtle" or "CTurtle"?

Either one works. The "C" prefix is a nod to the single dependency of this project, CImg. CTurtle quickly became the preference in reference to the name of the header file, "CTurtle.hpp", whereas C-Turtle was originally though to be its proper name. As time has progressed, the two spellings have become synonymous in meaning.

Direct Comparison between C++ and Python

The following table contains examples, which do the exact same thing, between C-Turtle and Python's Turtle.

C++ Python
  #include "CTurtle.hpp"

  namespace ct = cturtle;

  int main(int argc, char** argv) {
      ct::TurtleScreen scr;
      ct::Turtle turtle(scr);
      turtle.speed(ct::TS_SLOWEST);
      turtle.fillcolor({"purple"});
      turtle.begin_fill();
      for (int i = 0; i < 4; i++) {
          turtle.forward(50);
          turtle.right(90);
      }
      turtle.end_fill();
      scr.bye();
      return 0;
  }

  
  import turtle

  turt = turtle.Turtle()
  turt.fillcolor("purple")
  turt.speed("slowest")

  turt.begin_fill()
  for i in range(4):
      turt.forward(50)
      turt.right(90)
  turt.end_fill()

  turt.bye()

   

Headless Mode

C-Turtle also supports drawing to an animated GIF instead of a display (e.g, "headless"). This is configurable through the "headless" preprocessor definitions, seen in following example. To write GIFs, C-Turtle uses jo_gif, a wonderful public domain GIF library created by Jon Olick. This avoids having ImageMagick as a dependency, which is what CImg uses by default to save animated GIFs.

In "headless" mode, TurtleScreen has all functionality relating to input and background images removed. This is due to 1) the lack of a display to receive event notifications, and 2) the lack of a guarantee of a safely-usable filesystem to load images from. It does work under the assumption that the filesystem is safe to save to, however.

//Make special note of these defines prior to usage.
#define CTURTLE_HEADLESS //Define to configure CTurtle for Headless mode.

#define CTURTLE_HEADLESS_SAVEDIR "./test.gif" //Optional define, default is "./cturtle.gif".
#define CTURTLE_HEADLESS_WIDTH 800 //Optional define, default is 400
#define CTURTLE_HEADLESS_HEIGHT 600 //Optional define, default is 300

#include "CTurtle.hpp"

namespace ct = cturtle;

int main(int argc, char** argv) {
    ct::TurtleScreen scr;
    ct::Turtle rt(scr);

    for(int i = 0; i < 4; i++){
        rt.forward(50);
        rt.right(90);
    }

    scr.bye();
    return 0;
}

Why does headless mode take so long to save a GIF file?

A frame is added to the resulting GIF for every change in state for a Turtle. This includes rotation, pen changes, size changes, etcetera. You can choose to display only every N frames, and thus save only every N frames, by taking advantage of tracer settings (see tracer(int countmax, unsigned int delayMS) function in TurtleScreen documentation). This dramatically reduces file size and write time in exchange for less frames in the image.

Why does headless mode print HTML + Base64 by default?

Headless mode was developed with the intention of being embedded in web applications, namely Runestone Interactive textbooks. As such, it prints HTML to display the results of the executed code by printing a Base64-encoded version of the resulting GIF file. This lets CTurtle be very easily embedded without needing any extra tricks or external File IO with any kind of backend. This can be disabled by having #define CTURTLE_HEADLESS_NO_HTML before the inclusion of CTurtle.

Examples and Derivative Works

Packaged alongside CTurtle

These examples can be found in the examples directory at the root of this repository. Many are derived from Runestone Interactive textbooks, such as the Sierpinski Triangle, Knight's Tour, Multiple Turtles, and Recursion Tree examples. Others, such as the Koch Fractal examples, are derived from Berea College coursework and were manually converted from Python.

Derivative Works

The following four works are shared with permission of their creator, Dr. Mark Liu, from the University of Kentucky. These are fantastic examples of games, and voice-controlled play provides a particularly interesting change from command-line or button-based interfaces.

Student Work Showcase

As time progresses, and as I am afforded the opportunity, I will provide visual examples of work students have done using this library. None of these are produced by my own work (but did use C-Turtle in their generation), however permission was given to post the works here!

Three examples of artwork generated in the style of Piet Mondrian as part of an assignment on Recursion. Β 

Azis Toktobaev - Berea College

Mondrian Art Example 1 Β 

Bryar Frank - Berea College

Mondrian Art Example 2 Β 

Karina Agliullova - Berea College

Mondrian Art Example 3