├── .gitignore ├── LICENSE ├── README.rst ├── Vagrantfile ├── classroom-code ├── Click here to get started with the class!.ipynb ├── examples │ ├── astrotutor_magic.ipynb │ ├── blink.ipynb │ ├── brooksc_findpos.ipynb │ ├── brooksc_flatmap50.ipynb │ ├── brooksc_teleport_pad.ipynb │ ├── brooksc_template.ipynb │ ├── brooksc_tntsnake.ipynb │ ├── burnaron_bunkermatic.ipynb │ ├── burnaron_bunkermatic2.ipynb │ ├── clear.ipynb │ ├── coderdojo.ipynb │ ├── danielbates_minecraft_basic.ipynb │ ├── danielbates_setblockdemo.ipynb │ ├── davef21370_maze.ipynb │ ├── daviewales_minesweeper.ipynb │ ├── fleap_railgen.ipynb │ ├── flying.ipynb │ ├── gf_clearZone.ipynb │ ├── gf_drawbuilding.ipynb │ ├── gf_helloworld.ipynb │ ├── hello.ipynb │ ├── hello_world.ipynb │ ├── jjinux_sierpinski_triangle.ipynb │ ├── mg-spiral_tower.ipynb │ ├── minecraft_letters.ipynb │ ├── minescan.ipynb │ ├── obsidz_teleport.ipynb │ ├── pileup.ipynb │ ├── pyramid.ipynb │ ├── pyramid_shell.ipynb │ ├── sleepyoz_analogclock.ipynb │ ├── sleepyoz_digitalclock.ipynb │ ├── sleepyoz_digitalclock2.ipynb │ ├── sleepyoz_digitalclock3.ipynb │ ├── snowbound_flatmap.ipynb │ ├── sphere.ipynb │ ├── sphere_hollow.ipynb │ ├── stuffaboutcode_basics.ipynb │ ├── stuffaboutcode_bridge.ipynb │ ├── stuffaboutcode_clock.ipynb │ ├── stuffaboutcode_hideandseek.ipynb │ ├── tnt.ipynb │ ├── tower.ipynb │ ├── tower2.ipynb │ └── zhuowei_rainbow.ipynb ├── exercises │ ├── Exercise 0 -- Where are we? What are we doing?.ipynb │ ├── Exercise 1 -- Hello World.ipynb │ ├── Exercise 2 -- Getting Started with IPython.ipynb │ ├── Exercise 3 -- Basic Python Syntax.ipynb │ ├── Exercise 4 -- Change the Minecraft world using Python.ipynb │ ├── Exercise 5 -- Minecraft changes trigger activity in Python.ipynb │ └── images │ │ └── programming-environment.png └── turtle-examples │ ├── 3dfractaltree.ipynb │ ├── 3dfractaltree_colors.ipynb │ ├── 3dnautilus.ipynb │ ├── LICENSE │ ├── README-minecraft-turtle.md │ ├── adventuresinrpi.ipynb │ ├── circle.ipynb │ ├── fractal.ipynb │ ├── fractaltree.ipynb │ ├── pattern.ipynb │ ├── spiral.ipynb │ └── squares.ipynb ├── docs ├── Makefile ├── class-materials │ ├── Class Kickoff Deck.pdf │ └── Class Kickoff Deck.pptx ├── classroom │ ├── _images │ │ ├── coordinates.png │ │ ├── hello-world-minecraft.png │ │ ├── hello-world-notebook.png │ │ ├── ipython-notebook.png │ │ ├── lab-instance-connection-card.png │ │ ├── minecraft-profile.png │ │ └── programming-environment.png │ ├── exercises.rst │ ├── index.rst │ ├── lab-instance.rst │ ├── mcpi.rst │ ├── other-scripts.rst │ ├── overview.rst │ ├── player-controls.rst │ ├── resources.rst │ ├── setup.rst │ ├── test.rst │ ├── wifi.rst │ └── your-own-thing.rst ├── conf.py ├── contents.rst ├── faq │ └── index.rst ├── glossary.rst ├── index.rst ├── make.bat ├── mentors │ ├── general.rst │ ├── index.rst │ ├── lab-server.rst │ ├── lessons-learned.rst │ ├── maintenance.rst │ ├── project-technology.rst │ └── python-minecraft.rst ├── other-setups │ ├── index.rst │ ├── osx.rst │ ├── ubuntu.rst │ ├── vagrant.rst │ └── windows.rst ├── reference │ ├── architecture.rst │ └── index.rst ├── release-notes.rst └── todo.rst ├── fabfile.py ├── lab-server ├── README.rst ├── Vagrantfile ├── canary-build-image │ ├── Dockerfile │ └── README.rst ├── controller │ ├── .gitignore │ ├── LICENSE │ ├── README.rst │ ├── cliffuni │ │ ├── __init__.py │ │ └── formatters.py │ ├── lsc │ │ ├── __init__.py │ │ ├── commands │ │ │ ├── __init__.py │ │ │ ├── environment.py │ │ │ └── lab.py │ │ ├── config.py │ │ ├── model │ │ │ ├── __init__.py │ │ │ ├── controlsheet.py │ │ │ └── instance.py │ │ └── shell.py │ ├── requirements.txt │ └── setup.py ├── lab-server-setup.sh └── student-env-image │ ├── Dockerfile │ ├── README.rst │ ├── commands │ ├── run-canary.sh │ ├── run-ipython-notebook.sh │ └── sync-notebooks.sh │ ├── default-canary-files │ ├── config │ │ ├── db.cfg │ │ ├── motd.txt │ │ ├── ops.cfg │ │ ├── server.cfg │ │ └── worlds │ │ │ └── default │ │ │ └── default_NORMAL.cfg │ ├── db │ │ ├── ban.xml │ │ ├── operators.xml │ │ ├── permission.xml │ │ ├── reservelist.xml │ │ └── whitelist.xml │ ├── eula.txt │ └── worlds │ │ └── scoreboards │ │ └── session.lock │ └── minecraft-lab.conf ├── mcpi ├── __init__.py ├── block.py ├── connection.py ├── event.py ├── minecraft.py ├── util.py └── vec3.py ├── mcpiext ├── LICENSE-minecraft-stuff ├── LICENSE-minecraft-turtle ├── README-minecraft-stuff.md ├── README-minecraft-turtle.md ├── __init__.py ├── minecraftstuff.py └── minecraftturtle.py ├── requirements.txt ├── sample_config.yaml └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | .DS_Store 4 | *~ 5 | *.pyc 6 | *.swp 7 | .coverage 8 | *.log 9 | node_modules 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Packages 15 | *.egg 16 | *.egg-info 17 | dist 18 | build 19 | eggs 20 | parts 21 | bin 22 | var 23 | sdist 24 | develop-eggs 25 | .installed.cfg 26 | lib 27 | lib64 28 | __pycache__ 29 | 30 | # Installer logs 31 | pip-log.txt 32 | 33 | # Unit test / coverage reports 34 | .coverage 35 | .tox 36 | nosetests.xml 37 | 38 | # Translations 39 | *.mo 40 | 41 | # Mr Developer 42 | .mr.developer.cfg 43 | .project 44 | .pydevproject 45 | 46 | # jetbrains/pycharm 47 | .idea 48 | 49 | **/.vagrant 50 | docs/_build/* 51 | **/private_config.yaml 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 CoderDojo Twin Cities 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ================================= 2 | CoderDoto TC's python-minecraft 3 | ================================= 4 | 5 | This repository contains the course material for the `CoderDojo Twin 6 | Cities'`_ *Building worlds in Minecraft with Python* code 7 | group. Complete documentation is available in our `Read the Docs 8 | project`_. 9 | 10 | .. _CoderDojo Twin Cities': http://www.coderdojotc.org/ 11 | .. _Read the Docs project: http://coderdojotc.readthedocs.org/projects/python-minecraft/ 12 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 5 | # !!!!! YOU MUST CONFIGURE SOME SETTINGS BEFORE YOU CAN USE THIS !!!!! 6 | # !!!!! Read below under the CONFIGURE BEFORE USE heading. !!!!! 7 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 8 | 9 | # This Vagrantfile sets up a python-minecraft lab server 10 | # environment. This is the same environment used during our CoderDojo 11 | # classroom events. For more details, visit the documentation at: 12 | # 13 | # http://python-minecraft.readthedocs.org/en/latest/other-setups/vagrant.html 14 | # 15 | # CONFIGURE BEFORE USE 16 | # 17 | # Some settings must be added to a file named "private_config.yaml" in 18 | # the top level directory before you start up the environment using 19 | # Vagrant. Open the file named "sample_config.yaml", save it to a new 20 | # file named "private_config.yaml", and make the necessary edits. Read 21 | # the documentation linked above for more support. 22 | 23 | # This lab server environment uses Docker to create a 24 | # private environment for each student. Each environment consists of a 25 | # CanaryMod server, configured with the RaspberryJuice plugin, and set 26 | # up to host a Minecraft world. It also includes an IPython Notebook 27 | # server, configured to allow students to work through the exercises 28 | # of the python-minecraft code group. 29 | 30 | require 'yaml' 31 | 32 | current_dir = File.dirname(File.expand_path(__FILE__)) 33 | private_config = YAML.load_file("#{current_dir}/private_config.yaml") 34 | 35 | 36 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 37 | VAGRANTFILE_API_VERSION = "2" 38 | 39 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 40 | # Provider-specific configuration so you can fine-tune various 41 | # backing providers for Vagrant. These expose provider-specific options. 42 | # Example for VirtualBox: 43 | # 44 | config.vm.provider "docker" do |d| 45 | d.image = private_config['image_name'] 46 | d.ports = ["10443:8888", "10565:25565"] 47 | d.env = { 48 | "MOJANG_ACCOUNTS" => private_config['mojang_account'], 49 | "STUDENT_PASSWORD" => private_config['ipython_password'], 50 | "CODERDOJO_REPO" => private_config['coderdojo_source_code'], 51 | } 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /classroom-code/Click here to get started with the class!.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Overview of Today's Class\n", 8 | "\n", 9 | "This section describes how we normally work in the CoderDojo classroom and what to expect in today's session.\n", 10 | "\n", 11 | "\n", 12 | "## Organization and Introductions\n", 13 | "\n", 14 | "We try to have around three students per mentor. After you first get settled into your seat, take a few moments to get to know the mentors and the other students sitting near you. Here are some example questions to break the ice:\n", 15 | "\n", 16 | "* What's your name?\n", 17 | "\n", 18 | "* Have you attended (or mentored) this class before?\n", 19 | "\n", 20 | "* What kind of experience do you have with programming?\n", 21 | "\n", 22 | "* Why did you come to this class today? What are you hoping to do or learn?\n", 23 | "\n", 24 | "Be sure to talk to the people around you. You may have something to teach them, and they may know something you want to learn. This isn't a library, so you won't get into trouble for talking. Making friends, sharing stories, and working together are all OK.\n", 25 | "\n", 26 | "\n", 27 | "## Learning Objectives\n", 28 | "\n", 29 | "\n", 30 | "Here are some of the things you will learn while participating in today's class:\n", 31 | "\n", 32 | "* How to read, write, and run code in IPython\n", 33 | "\n", 34 | "* Basic Python syntax\n", 35 | "\n", 36 | "* How to change the Minecraft world using Python\n", 37 | "\n", 38 | "* How to have the Minecraft world trigger activity in Python\n", 39 | "\n", 40 | "* Anything else you want! Be sure to talk to a mentor if there is something specific you are looking to learn.\n", 41 | "\n", 42 | "\n", 43 | "## Order of Events\n", 44 | "\n", 45 | "Here's how things typically happen in the CoderDojo classroom:\n", 46 | "\n", 47 | "1. Get connected. This means getting your PC onto the Wi-Fi network, and then getting connected to your [lab instance](http://coderdojotc.readthedocs.org/projects/python-minecraft/en/latest/glossary.html#term-lab-instance). If you are reading this document from inside the Jupyter interface, you are probably already done with this step.\n", 48 | "\n", 49 | "2. Work through each exercise. We have several exercises, each designed to teach you different things about the Jupyter notebook environment, Python programming, and interacting with Minecraft through Python code. The exercises are numbered, and it's a good idea to tackle them in order. Open the [exercises folder](exercises) to get started.\n", 50 | "\n", 51 | "3. Look at the other examples. See if you can understand what they do, and think about how you might want to change them. Then give it a try! Open the [examples folder](examples) to get started. In addition to the conventional examples, we also have a [folder of turtle-based examples](turtle-examples), which let you draw in the Minecraft world like you would in in a Scratch environment.\n", 52 | " \n", 53 | "4. If you brought your own PC to class today, set a copy of our classroom environment on your own PC. This will let you continue working on this at home. [This page](http://coderdojotc.readthedocs.org/projects/python-minecraft/en/latest/other-setups/vagrant.html) will walk you through the steps.\n", 54 | "\n", 55 | "\n", 56 | "## Ground Rules\n", 57 | "\n", 58 | "In CoderDojo, **the one rule is \"be cool\".** Putting this into practice in the classroom, you can be cool by:\n", 59 | "\n", 60 | "* **Helping each other.** Check with other students before asking a mentor for help. \"Ask three, then me,\" is a good rule of thumb.\n", 61 | "\n", 62 | "* **Learning Python.** Today's focus is on programming, not the game of Minecraft. Remember, this is a CoderDojo, not a LAN party!\n" 63 | ] 64 | } 65 | ], 66 | "metadata": { 67 | "kernelspec": { 68 | "display_name": "Python 2", 69 | "language": "python", 70 | "name": "python2" 71 | }, 72 | "language_info": { 73 | "codemirror_mode": { 74 | "name": "ipython", 75 | "version": 2 76 | }, 77 | "file_extension": ".py", 78 | "mimetype": "text/x-python", 79 | "name": "python", 80 | "nbconvert_exporter": "python", 81 | "pygments_lexer": "ipython2", 82 | "version": "2.7.6" 83 | } 84 | }, 85 | "nbformat": 4, 86 | "nbformat_minor": 0 87 | } 88 | -------------------------------------------------------------------------------- /classroom-code/examples/blink.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#Note: \n", 8 | "\n", 9 | "THIS SCRIPT WILL RUN FOREVER IF YOU LET IT.\n", 10 | "\n", 11 | "Use the Kernel-->Interupt menu option to stop it." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "#!/usr/bin/python\n", 23 | "# Written by Eric Johnson for CoderDojo Twin Cities - www.coderdojotc.org\n", 24 | "# Creates a block, near the player's initial position, that changes material each second\n", 25 | "import mcpi.minecraft as minecraft\n", 26 | "import mcpi.block as block\n", 27 | "import time\n", 28 | "\n", 29 | "# Connect to the Minecraft server\n", 30 | "world = minecraft.Minecraft.create()\n", 31 | "\n", 32 | "# Get the player's current position and store the coordinates\n", 33 | "[x, y, z] = world.player.getPos()\n", 34 | "\n", 35 | "materials = [block.GRASS, block.WOOL, block.BRICK_BLOCK]\n", 36 | "n = 0\n", 37 | "while True:\n", 38 | " n = (n + 1) % len(materials)\n", 39 | " material = materials[n]\n", 40 | " world.setBlock(x+1, y, z+1, material)\n", 41 | " time.sleep(1)" 42 | ] 43 | } 44 | ], 45 | "metadata": { 46 | "kernelspec": { 47 | "display_name": "Python 2", 48 | "language": "python", 49 | "name": "python2" 50 | }, 51 | "language_info": { 52 | "codemirror_mode": { 53 | "name": "ipython", 54 | "version": 2 55 | }, 56 | "file_extension": ".py", 57 | "mimetype": "text/x-python", 58 | "name": "python", 59 | "nbconvert_exporter": "python", 60 | "pygments_lexer": "ipython2", 61 | "version": "2.7.6" 62 | } 63 | }, 64 | "nbformat": 4, 65 | "nbformat_minor": 0 66 | } 67 | -------------------------------------------------------------------------------- /classroom-code/examples/brooksc_findpos.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#import the minecraft.py module from the minecraft directory\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "#import minecraft block module\n", 16 | "import mcpi.block as block\n", 17 | "#import time, so delays can be used\n", 18 | "import time\n", 19 | "\n", 20 | "if __name__ == \"__main__\":\n", 21 | " mc = minecraft.Minecraft.create()\n", 22 | "# mc.postToChat(\"Flattening surface\")\n", 23 | "# mc.setBlocks(-128,0,-128,128,64,128,0)\n", 24 | "# mc.setBlocks(-128,0,-128,128,-64,128,block.SANDSTONE.id)\n", 25 | "# mc.postToChat(\"Putting a diamong block at 0,0,0\")\n", 26 | "# mc.setBlock(0,0,0,block.DIAMOND_BLOCK.id)\n", 27 | "\n", 28 | " while True:\n", 29 | " #Find out your players position\n", 30 | " playerPos = mc.player.getPos()\n", 31 | " mc.postToChat(\"Find your position - its x=%s y=%s z=%s\" % (int(playerPos.x), int(playerPos.y), int(playerPos.z)))\n", 32 | "# mc.postToChat(\"Find your position - its x=%.2f y=%.2f z=%.2f\" % (playerPos.x, playerPos.y, playerPos.z))\n", 33 | " time.sleep(1)" 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 0 40 | } -------------------------------------------------------------------------------- /classroom-code/examples/brooksc_flatmap50.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#import the minecraft.py module from the minecraft directory\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "#import minecraft block module\n", 16 | "import mcpi.block as block\n", 17 | "#import time, so delays can be used\n", 18 | "\n", 19 | "def main():\n", 20 | " mc = minecraft.Minecraft.create()\n", 21 | " # write the rest of your code here...\n", 22 | " mc.postToChat(\"Erasing a 50x50 block...\")\n", 23 | " mc.setBlocks(-50,-10,-50,50,10,50,block.AIR.id)\n", 24 | " mc.setBlocks(-50,0,-50,50,-10,50,block.SANDSTONE.id)\n", 25 | " mc.postToChat(\"Done Erasing a 50x50 block!\")\n", 26 | "\n", 27 | "\n", 28 | "\n", 29 | "if __name__ == \"__main__\":\n", 30 | " main()" 31 | ] 32 | } 33 | ], 34 | "metadata": {}, 35 | "nbformat": 4, 36 | "nbformat_minor": 0 37 | } -------------------------------------------------------------------------------- /classroom-code/examples/brooksc_teleport_pad.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "# as shared on mcpipy.com\n", 14 | "\n", 15 | "import mcpi.minecraft as minecraft\n", 16 | "import mcpi.block as block\n", 17 | "import time\n", 18 | "\n", 19 | "\n", 20 | "# If you are running this script with the bukkit mod, then use a diamond block as the magic center block for teleporting\n", 21 | "# comment/uncomment below as appropriate\n", 22 | "magic_block = block.DIAMOND_BLOCK # for bukkit server\n", 23 | "#magic_block = block.NETHER_REACTOR_CORE # for raspberry pi\n", 24 | "\n", 25 | "if __name__ == \"__main__\": # The script\n", 26 | " mc = minecraft.Minecraft.create()\n", 27 | " loc = mc.player.getPos()\n", 28 | " x = loc.x\n", 29 | " y = loc.y - 1\n", 30 | " z = loc.z\n", 31 | " for z_z in range (int(z-1), int(z+2)):\n", 32 | " for x_x in range(int(x-1), int(x+2)):\n", 33 | " mc.setBlock(x_x,y,z_z, block.COBBLESTONE)\n", 34 | " mc.setBlock(x_x,y+1,z_z, block.AIR)\n", 35 | "\n", 36 | "mc.setBlock(x,y,z, magic_block)" 37 | ] 38 | } 39 | ], 40 | "metadata": {}, 41 | "nbformat": 4, 42 | "nbformat_minor": 0 43 | } -------------------------------------------------------------------------------- /classroom-code/examples/brooksc_template.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#import the minecraft.py module from the minecraft directory\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "#import minecraft block module\n", 16 | "import mcpi.block as block\n", 17 | "#import time, so delays can be used\n", 18 | "\n", 19 | "def main():\n", 20 | " mc = minecraft.Minecraft.create()\n", 21 | " # write the rest of your code here...\n", 22 | " mc.postToChat(\"Hello MCPIPY World!\")\n", 23 | "\n", 24 | "\n", 25 | "if __name__ == \"__main__\":\n", 26 | " main()" 27 | ] 28 | } 29 | ], 30 | "metadata": {}, 31 | "nbformat": 4, 32 | "nbformat_minor": 0 33 | } -------------------------------------------------------------------------------- /classroom-code/examples/clear.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "import sys\n", 15 | "\n", 16 | "\"\"\" clearZone clears an area and sets a stone floor\n", 17 | " takes two x,z pairs clears everything above 0y and then sets\n", 18 | " a stone floor at -1y\n", 19 | " @author: goldfish\n", 20 | "\n", 21 | "\tModified by Jessica Zehavi for CoderDojo Twin Cities\n", 22 | "\thttp://www.coderdojotc.org \n", 23 | "\"\"\"\n", 24 | "\n", 25 | "def clearZone( size ):\n", 26 | "\tmc.player.setPos(0,0,0)\n", 27 | "\t[x,y,z] = [0,0,0];\n", 28 | "\tmc.setBlocks( x - size, 0, z - size, x + size, size, z + size, block.AIR )\n", 29 | "\tmc.setBlocks( x - size , -1, z - size, x + size, -1, z + size, block.STONE )\n", 30 | "\n", 31 | "if __name__ == \"__main__\":\n", 32 | "\tmc = minecraft.Minecraft.create( )\n", 33 | "\n", 34 | "\ttry:\n", 35 | "\t\tsize = sys.argv[1]\n", 36 | "\t\tmc.postToChat( \"Clearing things up a bit...\" )\n", 37 | "\t\tprint \"Clearing a\", size, \"x\", size, \"area around your position.\"\n", 38 | "\t\tclearZone( int(size) )\n", 39 | "\texcept:\n", 40 | "\t\tprint \"Specify the size of zone you would like to clear.\"\n", 41 | "\t\tprint \"Syntax:\", sys.argv[0], \"\"" 42 | ] 43 | } 44 | ], 45 | "metadata": {}, 46 | "nbformat": 4, 47 | "nbformat_minor": 0 48 | } -------------------------------------------------------------------------------- /classroom-code/examples/coderdojo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "import minecraft_letters as letters\n", 15 | "\n", 16 | "# Connect to the Minecraft server\n", 17 | "world = minecraft.Minecraft.create()\n", 18 | "\n", 19 | "letters.write( world, \"Rock AND Roll\", block.TNT );" 20 | ] 21 | } 22 | ], 23 | "metadata": {}, 24 | "nbformat": 4, 25 | "nbformat_minor": 0 26 | } -------------------------------------------------------------------------------- /classroom-code/examples/danielbates_minecraft_basic.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "# Don't execute this directory -- this is a support script for danielbates_setblockdemo.py\n", 12 | "\n", 13 | "import sys\n", 14 | "\n", 15 | "# Add some common locations where the main API might be. Feel free to add/change\n", 16 | "# these to suit you.\n", 17 | "sys.path.append(\"mcpi\")\n", 18 | "sys.path.append(\"api/python/mcpi\")\n", 19 | "sys.path.append(\"mcpi/api/python/mcpi\")\n", 20 | "\n", 21 | "# Attempt to import Mojang's API.\n", 22 | "try:\n", 23 | "\timport connection\n", 24 | "\timport minecraft\n", 25 | "except ImportError:\n", 26 | "\tprint \"Unable to find Minecraft API. Please place minecraft_basic.py in the mcpi directory.\"\n", 27 | "\texit()\n", 28 | "\n", 29 | "_server = None\n", 30 | "_blockedit = None\n", 31 | "_playeredit = None\n", 32 | "\n", 33 | "def connect(ip=\"127.0.0.1\", port=4711):\n", 34 | "\tglobal _server, _blockedit, _playeredit\n", 35 | "\t\n", 36 | "\ttry:\n", 37 | "\t\t_server = connection.Connection(ip, port)\n", 38 | "\t\t_blockedit = minecraft.Minecraft(_server)\n", 39 | "\t\t_playeredit = _blockedit.player\n", 40 | "\texcept Exception:\n", 41 | "\t\tprint \"Unable to connect to Minecraft server at {0}:{1}\".format(ip,port)\n", 42 | "\t\treturn\n", 43 | "\n", 44 | "\tprint \"Connected to Minecraft server at {0}:{1}\".format(ip,port)\n", 45 | "\n", 46 | "def setblock(x,y,z,*typedata):\n", 47 | "\t_blockedit.setBlock(x,y,z,typedata)\n", 48 | "\n", 49 | "def getblock(x,y,z):\n", 50 | "\treturn _blockedit.getBlock(x,y,z)\n", 51 | "\n", 52 | "def moveplayer(x,y,z):\n", 53 | "\t_playeredit.setPos(x,y,z)\n", 54 | "\n", 55 | "AIR = 0\n", 56 | "STONE = 1\n", 57 | "GRASS = 2\n", 58 | "DIRT = 3\n", 59 | "COBBLESTONE = 4\n", 60 | "WOOD_PLANK = 5\n", 61 | "SAPLING = 6\n", 62 | "BEDROCK = 7\n", 63 | "WATER_FLOWING = 8\n", 64 | "WATER = 9\n", 65 | "LAVA_FLOWING = 10\n", 66 | "LAVA = 11\n", 67 | "SAND = 12\n", 68 | "GRAVEL = 13\n", 69 | "GOLD_ORE = 14\n", 70 | "IRON_ORE = 15\n", 71 | "COAL_ORE = 16\n", 72 | "WOOD = 17\n", 73 | "LEAVES = 18\n", 74 | "GLASS = 20\n", 75 | "LAPIS_ORE = 21\n", 76 | "LAPIS = 22\n", 77 | "SANDSTONE = 24\n", 78 | "BED = 26\n", 79 | "COBWEB = 30\n", 80 | "TALL_GRASS = 31\n", 81 | "WOOL = 35\n", 82 | "FLOWER_YELLOW = 37\n", 83 | "FLOWER_RED = 38\n", 84 | "MUSHROOM_BROWN = 39\n", 85 | "MUSHROOM_RED = 40\n", 86 | "GOLD = 41\n", 87 | "IRON = 42\n", 88 | "STONE_SLAB_DOUBLE = 43\n", 89 | "STONE_SLAB = 44\n", 90 | "BRICK = 45\n", 91 | "TNT = 46\n", 92 | "BOOKSHELF = 47\n", 93 | "MOSSY_STONE = 48\n", 94 | "TORCH = 50\n", 95 | "FIRE = 51\n", 96 | "WOOD_STAIRS = 53\n", 97 | "CHEST = 54\n", 98 | "DIAMOND_ORE = 56\n", 99 | "DIAMOND = 57\n", 100 | "CRAFTING_TABLE = 58\n", 101 | "FARMLAND = 60\n", 102 | "FURNACE = 61\n", 103 | "FURNACE_ACTIVE = 62\n", 104 | "WOOD_DOOR = 64\n", 105 | "LADDER = 65\n", 106 | "COBBLESTONE_STAIRS = 67\n", 107 | "IRON_DOOR = 71\n", 108 | "REDSTONE_ORE = 73\n", 109 | "SNOW_COVER = 78\n", 110 | "ICE = 79\n", 111 | "SNOW = 80\n", 112 | "CACTUS = 81\n", 113 | "CLAY = 82\n", 114 | "SUGAR_CANE = 83\n", 115 | "FENCE = 85\n", 116 | "GLOWSTONE = 89\n", 117 | "INVISIBLE_BEDROCK = 95\n", 118 | "STONE_BRICK = 98\n", 119 | "GLASS_PANE = 102\n", 120 | "MELON = 103\n", 121 | "FENCE_GATE = 107\n", 122 | "GLOWING_OBSIDIAN = 246\n", 123 | "NETHER_REACTOR_CORE = 247\n", 124 | "UPDATE_GAME_BLOCK = 249" 125 | ] 126 | } 127 | ], 128 | "metadata": {}, 129 | "nbformat": 4, 130 | "nbformat_minor": 0 131 | } -------------------------------------------------------------------------------- /classroom-code/examples/fleap_railgen.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#import the minecraft.py module from the minecraft directory\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "#import minecraft block module\n", 16 | "import mcpi.block as block\n", 17 | "#import time, so delays can be used\n", 18 | "\n", 19 | "def main():\n", 20 | " mc = minecraft.Minecraft.create()\n", 21 | " # an abbrieviated flatmap\n", 22 | "# mc.setBlocks(-50,-10,-50,50,10,50,block.AIR.id)\n", 23 | "# mc.setBlocks(-50,0,-50,50,-10,50,block.SANDSTONE.id)\n", 24 | " # The original flatmap\n", 25 | " mc.setBlocks(-128,0,-128,128,64,128,0)\n", 26 | " mc.setBlocks(-128,0,-128,128,-64,128,block.SANDSTONE.id)\n", 27 | "\n", 28 | " # exit()\n", 29 | " mc.postToChat(\"Hello you have successfully ran Rail Gen :).\")\n", 30 | " # create the station\n", 31 | " mc.setBlock(1,3,0,block.GLOWSTONE_BLOCK.id)\n", 32 | " mc.setBlock(0,0,0,block.STONE_SLAB.id)\n", 33 | " mc.setBlock(-1,1,0,block.DOOR_WOOD.id,0)\n", 34 | " mc.setBlock(-1,2,0,block.DOOR_WOOD.id,8)\n", 35 | " mc.setBlock(0,1,1,block.STONE.id)\n", 36 | " mc.setBlock(0,2,1,block.STONE.id)\n", 37 | " mc.setBlock(0,1,-1,block.STONE.id)\n", 38 | " mc.setBlock(0,2,-1,block.STONE.id)\n", 39 | " mc.setBlock(1,1,1,block.STONE.id)\n", 40 | " mc.setBlock(-1,1,1,block.STONE.id)\n", 41 | " mc.setBlock(0,1,1,block.STONE.id)\n", 42 | " mc.setBlock(1,1,-1,block.STONE.id)\n", 43 | " mc.setBlock(-1,1,-1,block.STONE.id)\n", 44 | " mc.setBlock(-1,2,-1,block.GLOWSTONE_BLOCK.id)\n", 45 | " mc.setBlock(1,2,-1,block.STONE.id)\n", 46 | " mc.setBlock(1,2,1,block.STONE.id)\n", 47 | " mc.setBlock(-1,2,1,block.GLOWSTONE_BLOCK.id)\n", 48 | " mc.setBlock(-1,3,0,block.STONE_SLAB.id)\n", 49 | " mc.setBlock(0,3,0,block.STONE_SLAB.id)\n", 50 | " # Create the path one direction\n", 51 | " mc.setBlocks(129,0,1,0,0,-1,block.STONE_SLAB)\n", 52 | " mc.setBlocks(0,1,2,128,1,2,block.STONE.id)\n", 53 | " mc.setBlocks(128,1,-2,0,1,-2,block.STONE.id)\n", 54 | " mc.setBlocks(128,0,2,0,0,2,block.GLOWSTONE_BLOCK.id)\n", 55 | " mc.setBlocks(128,0,-2,0,0,-2,block.GLOWSTONE_BLOCK.id)\n", 56 | "\n", 57 | "\n", 58 | "\n", 59 | "\n", 60 | "\n", 61 | "if __name__ == \"__main__\":\n", 62 | " main()" 63 | ] 64 | } 65 | ], 66 | "metadata": {}, 67 | "nbformat": 4, 68 | "nbformat_minor": 0 69 | } -------------------------------------------------------------------------------- /classroom-code/examples/flying.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "from math import *\n", 15 | "\n", 16 | "# Connect to the Minecraft server\n", 17 | "world = minecraft.Minecraft.create()\n", 18 | "\n", 19 | "# Get the player's current position and store the coordinates\n", 20 | "[x,y,z] = world.player.getPos()\n", 21 | "\n", 22 | "# Look up the block material for the coordinate directly underneath the player\n", 23 | "blockId = world.getBlock( x, ceil( y ) - 1, z )\n", 24 | "\n", 25 | "# If the player's y coordinate position is greater than 0, then they must be \n", 26 | "# flying or walking on stilts! AIR has block ID 0 so if that's what is under\n", 27 | "# the player, they must be flying.\n", 28 | "flying = blockId == 0\n", 29 | "\n", 30 | "if flying:\n", 31 | "\tprint \"You are flying high!\"\n", 32 | "else:\n", 33 | "\tprint \"You are on the ground.\"" 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 0 40 | } -------------------------------------------------------------------------------- /classroom-code/examples/gf_clearZone.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "\n", 15 | "\"\"\" clearZone clears an area and sets a stone floor\n", 16 | " takes two x,z pairs clears everything above 0y and then sets\n", 17 | " a stone floor at -1y\n", 18 | " @author: goldfish\"\"\"\n", 19 | "\n", 20 | "def clearZone( alocx, alocz, blocx, blocz ):\n", 21 | " mc.setBlocks( alocx, 0, alocz, blocx, 64, blocz, block.AIR )\n", 22 | " mc.setBlocks( alocx, -1, alocz, blocx, -1, blocz, block.STONE )\n", 23 | "\n", 24 | "if __name__ == \"__main__\":\n", 25 | " mc = minecraft.Minecraft.create()\n", 26 | " clearZone( -20, -20, 20, 20 )" 27 | ] 28 | } 29 | ], 30 | "metadata": {}, 31 | "nbformat": 4, 32 | "nbformat_minor": 0 33 | } -------------------------------------------------------------------------------- /classroom-code/examples/gf_drawbuilding.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "import random\n", 15 | "\n", 16 | "\"\"\" draw a building\n", 17 | "\n", 18 | " @author: goldfish\"\"\"\n", 19 | "\n", 20 | "def drawBuilding( locx, locy, locz, floors, width, depth, floorheight, wallmaterial, floormaterial ):\n", 21 | " topx = locx+width\n", 22 | " topy = locy+((floorheight+1)*floors)\n", 23 | " topz = locz+depth\n", 24 | " #draw building shell\n", 25 | " mc.setBlocks( locx, locy, locz, topx, topy, topz, wallmaterial )\n", 26 | " mc.setBlocks( locx+1, locy+1, locz+1, topx-1, topy-1, topz-1, block.AIR )\n", 27 | " #draw floors\n", 28 | " if( floors > 1 ):\n", 29 | " for i in range( floors -1 ):\n", 30 | " floorYloc = locy+( (floorheight+1)*(i+1) )\n", 31 | " mc.setBlocks( locx+1, floorYloc, locz+1, topx-1, floorYloc, topz-1, floormaterial )\n", 32 | " #draw door\n", 33 | " doorloc = random.randint( 1, width-2 )\n", 34 | " mc.setBlock( locx, locy+1, locz+doorloc, block.AIR )\n", 35 | " mc.setBlock( locx, locy+2, locz+doorloc, block.AIR )\n", 36 | " #draw front windows\n", 37 | " if( floors > 1 ):\n", 38 | " for i in range( floors-1 ):\n", 39 | " windowYloc = locy+2+( (floorheight+1)*(i+1) )\n", 40 | " for j in range( floorheight-1 ):\n", 41 | " mc.setBlocks( locx, windowYloc+j , locz+1, locx, windowYloc+j, locz+(width-1), block.GLASS_PANE )\n", 42 | " #draw back windows\n", 43 | " if( floors > 1 ):\n", 44 | " for i in range( floors-1 ):\n", 45 | " windowYloc = locy+2+( (floorheight+1)*(i+1) )\n", 46 | " for j in range( floorheight-1 ):\n", 47 | " mc.setBlocks( locx+depth, windowYloc+j , locz+1, locx+depth, windowYloc+j, locz+(width-1), block.GLASS_PANE )\n", 48 | " #connect levels with ladder\n", 49 | " #mc.setBlocks( topx-1, locy+1, topz-1, topx-1, topy-1, topz-1, block.LADDER )\n", 50 | " \n", 51 | "if __name__ == \"__main__\":\n", 52 | " mc = minecraft.Minecraft.create()\n", 53 | " drawBuilding( 0, 20, 0, 5, 25, 5, 3, block.STONE, block.WOOD_PLANKS )" 54 | ] 55 | } 56 | ], 57 | "metadata": {}, 58 | "nbformat": 4, 59 | "nbformat_minor": 0 60 | } -------------------------------------------------------------------------------- /classroom-code/examples/gf_helloworld.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "\n", 14 | "\"\"\" hello world test app\n", 15 | "\n", 16 | " @author: goldfish\"\"\"\n", 17 | "\n", 18 | "mc = minecraft.Minecraft.create()\n", 19 | "mc.postToChat(\"Hello, Minecraft!\")" 20 | ] 21 | } 22 | ], 23 | "metadata": {}, 24 | "nbformat": 4, 25 | "nbformat_minor": 0 26 | } -------------------------------------------------------------------------------- /classroom-code/examples/hello.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import mcpi.minecraft as minecraft\n", 12 | "import mcpi.block as block\n", 13 | "\n", 14 | "world = minecraft.Minecraft.create()\n", 15 | "\n", 16 | "[x,y,z] = world.player.getPos()\n", 17 | "world.postToChat( \"Position is: %d %d %d\" % (x,y,z) )\n", 18 | "\n", 19 | "world.player.setPos( 0, 64, 0 )" 20 | ] 21 | } 22 | ], 23 | "metadata": {}, 24 | "nbformat": 4, 25 | "nbformat_minor": 0 26 | } -------------------------------------------------------------------------------- /classroom-code/examples/hello_world.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import mcpi.minecraft as minecraft\n", 13 | "import mcpi.block as block\n", 14 | "\n", 15 | "# Connect to the Minecraft server\n", 16 | "world = minecraft.Minecraft.create()\n", 17 | "\n", 18 | "world.postToChat(\"Hello Minecraft!\")" 19 | ] 20 | } 21 | ], 22 | "metadata": {}, 23 | "nbformat": 4, 24 | "nbformat_minor": 0 25 | } -------------------------------------------------------------------------------- /classroom-code/examples/jjinux_sierpinski_triangle.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "# mcpipy.com retrieved from URL below, written by jjinux\n", 14 | "# http://jjinux.blogspot.com/2013/05/drawing-sierpinskis-triangle-in.html\n", 15 | "\n", 16 | "\"\"\"Draw Sierpinski's triangle in Minecraft.\n", 17 | "\n", 18 | "See: http://jjinux.blogspot.com/2013/05/drawing-sierpinskis-triangle-in.html\n", 19 | "\n", 20 | "\"\"\"\n", 21 | "\n", 22 | "import random\n", 23 | "\n", 24 | "import mcpi.minecraft\n", 25 | "import mcpi.block as block\n", 26 | "\n", 27 | "# It goes from -MAX_XZ to MAX_XZ.\n", 28 | "MAX_XZ = 128\n", 29 | "MAX_Y = 64\n", 30 | "\n", 31 | "# These are the vertices of the triangle. It's a list of points. Each point\n", 32 | "# is an (X, Y, X) tuple.\n", 33 | "TRIANGLE_HEIGHT = MAX_Y - 1\n", 34 | "TOP = (-MAX_XZ, TRIANGLE_HEIGHT, 0)\n", 35 | "BOTTOM_LEFT = (MAX_XZ, TRIANGLE_HEIGHT, MAX_XZ)\n", 36 | "BOTTOM_RIGHT = (MAX_XZ, TRIANGLE_HEIGHT, -MAX_XZ)\n", 37 | "TRIANGLE_VERTICES = [TOP, BOTTOM_LEFT, BOTTOM_RIGHT]\n", 38 | "\n", 39 | "BASE_BLOCK_ID = block.SANDSTONE.id\n", 40 | "TRIANGLE_BLOCK_ID = block.SNOW.id\n", 41 | "\n", 42 | "# This is the maximum number of iterations to let the algorithm run. The\n", 43 | "# algorithm relies on randomness, so I'm just picking a sensible value.\n", 44 | "MAX_ITERATIONS = MAX_XZ ** 2\n", 45 | "\n", 46 | "PRINT_FREQ = 1000\n", 47 | "\n", 48 | "\n", 49 | "def clear_board(minecraft):\n", 50 | " minecraft.setBlocks(-MAX_XZ, 0, -MAX_XZ, MAX_XZ, MAX_Y, MAX_XZ, 0)\n", 51 | " minecraft.setBlocks(-MAX_XZ, 0, -MAX_XZ, MAX_XZ, -MAX_Y, MAX_XZ, BASE_BLOCK_ID)\n", 52 | "\n", 53 | "\n", 54 | "def draw_sierpinski_triangle(minecraft):\n", 55 | "\n", 56 | " def random_in_range():\n", 57 | " return random.randint(-MAX_XZ, MAX_XZ)\n", 58 | "\n", 59 | " def int_average(a, b):\n", 60 | " return int(round((a + b) / 2.0))\n", 61 | "\n", 62 | " # Draw the triangle vertices.\n", 63 | "\n", 64 | " for (x, y, z) in TRIANGLE_VERTICES:\n", 65 | " minecraft.setBlock(x, y, z, TRIANGLE_BLOCK_ID)\n", 66 | "\n", 67 | " # Pick a random point to start at.\n", 68 | "\n", 69 | " current = (random_in_range(),\n", 70 | " TRIANGLE_HEIGHT,\n", 71 | " random_in_range())\n", 72 | "\n", 73 | " for i in xrange(MAX_ITERATIONS):\n", 74 | "\n", 75 | " if i % PRINT_FREQ == 0:\n", 76 | " print(\"Drew %s blocks\" % i)\n", 77 | "\n", 78 | " # Pick a random vertex to \"walk\" toward.\n", 79 | "\n", 80 | " destination = random.choice(TRIANGLE_VERTICES)\n", 81 | "\n", 82 | " # Draw a block in the middle of the current location and the\n", 83 | " # destination.\n", 84 | "\n", 85 | " (c_x, c_y, c_z) = current\n", 86 | " (d_x, d_y, d_z) = destination\n", 87 | " current = (\n", 88 | " int_average(c_x, d_x),\n", 89 | " TRIANGLE_HEIGHT,\n", 90 | " int_average(c_z, d_z)\n", 91 | " )\n", 92 | " (x, y, z) = current\n", 93 | " minecraft.setBlock(x, y, z, TRIANGLE_BLOCK_ID)\n", 94 | "\n", 95 | "\n", 96 | "if __name__ == \"__main__\":\n", 97 | " minecraft = mcpi.minecraft.Minecraft.create()\n", 98 | "\n", 99 | " # Uncomment this if you need it.\n", 100 | " # clear_board(minecraft)\n", 101 | " \n", 102 | " draw_sierpinski_triangle(minecraft)" 103 | ] 104 | } 105 | ], 106 | "metadata": {}, 107 | "nbformat": 4, 108 | "nbformat_minor": 0 109 | } -------------------------------------------------------------------------------- /classroom-code/examples/mg-spiral_tower.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import mcpi.minecraft as minecraft\n", 12 | "import mcpi.block as block\n", 13 | "\n", 14 | "world = minecraft.Minecraft.create()\n", 15 | "\n", 16 | "[x0,y0,z0] = world.player.getPos()\n", 17 | "\n", 18 | "for " 19 | ] 20 | } 21 | ], 22 | "metadata": {}, 23 | "nbformat": 4, 24 | "nbformat_minor": 0 25 | } -------------------------------------------------------------------------------- /classroom-code/examples/minecraft_letters.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "# Written by Jessica Zehavi for CoderDojo Twin Cities - www.coderdojotc.org\n", 12 | "def write ( minecraft, text, material ):\n", 13 | "\tletters = { 'A' : [[1,0,0,1],[1,0,0,1],[1,1,1,1],[1,0,0,1],[0,1,1,0]],\n", 14 | "\t\t\t 'B' : [[1,1,1,0],[1,0,0,1],[1,1,1,0],[1,0,0,1],[1,1,1,0]],\n", 15 | "\t\t\t 'C' : [[0,1,1,0],[1,0,0,1],[1,0,0,0],[1,0,0,1],[0,1,1,0]],\n", 16 | "\t\t\t 'D' : [[1,1,1,0],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,1,1,0]],\n", 17 | "\t\t\t 'E' : [[1,1,1,1],[1,0,0,0],[1,1,1,1],[1,0,0,0],[1,1,1,1]],\n", 18 | "\t\t\t 'F' : [[1,1,1,1],[1,0,0,0],[1,1,1,1],[1,0,0,0],[1,0,0,0]],\n", 19 | "\t\t\t 'G' : [[1,1,1,0],[1,0,0,1],[1,0,0,0],[1,0,1,1],[0,1,1,0]],\n", 20 | "\t\t\t 'H' : [[1,0,0,1],[1,0,0,1],[1,1,1,1],[1,0,0,1],[1,0,0,1]],\n", 21 | "\t\t\t 'I' : [[1,1,1],[0,1,0],[0,1,0],[0,1,0],[1,1,1]],\n", 22 | "\t\t\t 'J' : [[0,1,1,0],[1,0,0,1],[0,0,0,1],[0,0,0,1],[0,0,0,1]],\n", 23 | "\t\t\t 'K' : [[1,0,0,1],[1,0,1,0],[1,1,0,0],[1,0,1,0],[1,0,0,1]],\n", 24 | "\t\t\t 'L' : [[1,1,1,1],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]],\n", 25 | "\t\t\t 'M' : [[1,0,0,0,1],[1,0,0,0,1],[1,0,1,0,1],[1,1,0,1,1],[1,0,0,0,1]],\n", 26 | "\t\t\t 'N' : [[1,0,0,0,1],[1,0,0,1,1],[1,0,1,0,1],[1,1,0,0,1],[1,0,0,0,1]],\n", 27 | "\t\t\t 'O' : [[0,1,1,0],[1,0,0,1],[1,0,0,1],[1,0,0,1],[0,1,1,0]],\n", 28 | "\t\t\t 'P' : [[1,0,0,0],[1,0,0,0],[1,1,1,1],[1,0,0,1],[1,1,1,1]],\n", 29 | "\t\t\t 'Q' : [[0,0,1,1],[0,1,1,0],[1,0,0,1],[1,0,0,1],[0,1,1,0]],\n", 30 | "\t\t\t 'R' : [[1,0,0,1],[1,0,1,0],[1,1,1,1],[1,0,0,1],[1,1,1,1]],\n", 31 | "\t\t\t 'S' : [[1,1,1,0],[0,0,0,1],[0,1,1,0],[1,0,0,0],[0,1,1,1]],\n", 32 | "\t\t\t 'T' : [[0,1,0],[0,1,0],[0,1,0],[0,1,0],[1,1,1]], \n", 33 | "\t\t\t 'U' : [[0,1,1,0],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1]],\n", 34 | "\t\t\t 'V' : [[0,0,1,0,0],[0,1,0,1,0],[0,1,0,1,0],[1,0,0,0,1],[1,0,0,0,1]],\n", 35 | "\t\t\t 'W' : [[0,1,0,1,0],[1,0,1,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,0,0,0,1]],\n", 36 | "\t\t\t 'X' : [[1,0,0,0,1],[0,1,0,1,0],[0,0,1,0,0],[0,1,0,1,0],[1,0,0,0,1]],\n", 37 | "\t\t\t 'Y' : [[0,0,1,0,0],[0,0,1,0,0],[0,1,0,1,0],[1,0,0,0,1],[1,0,0,0,1]],\n", 38 | "\t\t\t 'Z' : [[1,1,1,1,1],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[1,1,1,1,1]],\n", 39 | "\t\t\t ' ' : [[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]}\n", 40 | "\n", 41 | "\t# Get the player's current position\n", 42 | "\tpos = minecraft.player.getPos()\n", 43 | "\trow = 0\n", 44 | "\tkearning = 0\n", 45 | "\n", 46 | "\tfor letter in text.upper():\n", 47 | "\n", 48 | "\t\tprint letter\n", 49 | "\n", 50 | "\t\twhile row < len( letters[letter] ):\n", 51 | "\n", 52 | "\t\t\tcol = 0\n", 53 | "\n", 54 | "\t\t\twhile col < len( letters[letter][0] ):\n", 55 | "\n", 56 | "\t\t\t\t# If a block should be printed in that row/column for a \n", 57 | "\t\t\t\t# given letter, print it\n", 58 | "\t\t\t\tif letters[letter][row][col]:\n", 59 | "\t\t\t\t\tminecraft.setBlock( pos.x - col - kearning, pos.y + row + 1, pos.z, material )\n", 60 | "\n", 61 | "\t\t\t\tcol = col + 1\n", 62 | "\t\t\trow = row + 1\n", 63 | "\n", 64 | "\t\t# Reset the row and col for each letter\n", 65 | "\t\trow = 0\n", 66 | "\n", 67 | "\t\t# Adjust the spacing based on how big the letter is since this is \n", 68 | "\t\t# not a fixed width font\n", 69 | "\t\tkearning = kearning + len( letters[letter][0] ) + 1" 70 | ] 71 | } 72 | ], 73 | "metadata": {}, 74 | "nbformat": 4, 75 | "nbformat_minor": 0 76 | } -------------------------------------------------------------------------------- /classroom-code/examples/obsidz_teleport.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "import mcpi.minecraft as minecraft\n", 14 | "import mcpi.block as block\n", 15 | "import time\n", 16 | "\n", 17 | "\n", 18 | "#Author:\t\tObsidz\n", 19 | "#\n", 20 | "#Description: This is a teleport pad script.\n", 21 | "#\t\t\t To create a pad, place a nether reactor core onto a location and ring with cobbledtone blocks\n", 22 | "#\t\t\t To add to locations list walk over it\n", 23 | "#\n", 24 | "#Notes:\t\t Pads added to list by walking over them\n", 25 | "#\t\t\t Pads not removed if destroyed but can be teleported to but not from\n", 26 | "#\t\t\t You cannot teleport to the same pad without modifying script\n", 27 | "#\t\t\t Pads need to be added each time the script is run\n", 28 | "\n", 29 | "# modified version - as shared on mcpipy.com\n", 30 | "# original post @ http://www.minecraftforum.net/topic/1691618-teleportation-python-script/\n", 31 | "\n", 32 | "LPLoc = list()\n", 33 | " \n", 34 | "Pads = 0\n", 35 | "Cpad = 0\n", 36 | "\n", 37 | "# If you are running this script with the bukkit mod, then use a diamond block as the magic center block for teleporting\n", 38 | "# comment/uncomment below as appropriate\n", 39 | "magic_block = block.DIAMOND_BLOCK.id # for bukkit server\n", 40 | "#magic_block = block.NETHER_REACTOR_CORE.id # for raspberry pi\n", 41 | "\n", 42 | "def isLaunchPad(): #checks if the the location below the player is a teleporting pad\n", 43 | "\t\tloc = mc.player.getPos()\n", 44 | "\t\tif ((mc.getBlock(loc.x,loc.y-1,loc.z) == magic_block) and\n", 45 | "\t\t\t(mc.getBlock(loc.x-1,loc.y-1,loc.z-1) == block.COBBLESTONE.id) and\n", 46 | "\t\t\t(mc.getBlock(loc.x-1,loc.y-1,loc.z) == block.COBBLESTONE.id) and\n", 47 | "\t\t\t(mc.getBlock(loc.x-1,loc.y-1,loc.z+1) == block.COBBLESTONE.id) and\n", 48 | "\t\t\t(mc.getBlock(loc.x,loc.y-1,loc.z+1) == block.COBBLESTONE.id) and\n", 49 | "\t\t\t(mc.getBlock(loc.x,loc.y-1,loc.z-1) == block.COBBLESTONE.id) and\n", 50 | "\t\t\t(mc.getBlock(loc.x+1,loc.y-1,loc.z-1) == block.COBBLESTONE.id) and\n", 51 | "\t\t\t(mc.getBlock(loc.x+1,loc.y-1,loc.z) == block.COBBLESTONE.id) and\n", 52 | "\t\t\t(mc.getBlock(loc.x+1,loc.y-1,loc.z+1) == block.COBBLESTONE.id)):\n", 53 | "\t\t\taddLPLoc(loc)\n", 54 | "\t\t\treturn True\n", 55 | "\t\telse:\n", 56 | "\t\t\treturn False\n", 57 | "def addLPLoc(Vec3): #Loggs the location of the pad for future use\n", 58 | "\tglobal Pads\n", 59 | "\tglobal LPLoc\n", 60 | " \n", 61 | "\tinList = False\n", 62 | "\tif Pads > 0:\n", 63 | "\t\tfor loc in LPLoc:\n", 64 | "\t\t\tif (loc.x == Vec3.x and loc.y == Vec3.y and loc.z == Vec3.z):\n", 65 | "\t\t\t\tinList = True\n", 66 | "\t\t\t \n", 67 | "\tif not inList:\n", 68 | "\t\tLPLoc.append(Vec3)\n", 69 | "\t\tmc.postToChat(\"I'll remember this pad location!\")\n", 70 | "\t\tPads = len(LPLoc)\n", 71 | "def locCheck(): #Checks that you are not teleporting to the same pad\n", 72 | " \n", 73 | "\tglobal Cpad\n", 74 | "\tglobal LPLoc\n", 75 | "\tloc = mc.player.getPos()\n", 76 | "\tif (loc.x == LPLoc[Cpad].x and loc.y == LPLoc[Cpad].y and loc.z == LPLoc[Cpad].z):\n", 77 | "\t\tCpad = Cpad + 1\n", 78 | "def TPChar(): #sends the character to the next pad\n", 79 | "\tglobal Pads\n", 80 | "\tglobal Cpad\n", 81 | "\tglobal LPLoc\n", 82 | " \n", 83 | "\tif Pads > 1:\n", 84 | "\t\tmc.player.setPos(LPLoc[Cpad].x,LPLoc[Cpad].y + 1,LPLoc[Cpad].z)\n", 85 | "\t\tCpad = ( Cpad + 1) % Pads\n", 86 | "\t\ttime.sleep(3.0)\n", 87 | " \n", 88 | "if __name__ == \"__main__\": # The script\n", 89 | " \n", 90 | "\tmc = minecraft.Minecraft.create()\n", 91 | "\twhile True:\n", 92 | "\t\tif isLaunchPad():\n", 93 | "\t\t\tTPChar()\n", 94 | " \n", 95 | "\t\ttime.sleep(0.1)" 96 | ] 97 | } 98 | ], 99 | "metadata": {}, 100 | "nbformat": 4, 101 | "nbformat_minor": 0 102 | } -------------------------------------------------------------------------------- /classroom-code/examples/pileup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "# Written by Eric Johnson for CoderDojo Twin Cities - www.coderdojotc.org\n", 13 | "# Creates a rain of blocks around the player's current position\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "import time\n", 17 | "import random\n", 18 | "\n", 19 | "# Connect to the Minecraft server\n", 20 | "world = minecraft.Minecraft.create()\n", 21 | "\n", 22 | "print \"THIS SCRIPT WILL RUN FOREVER IF YOU LET IT\"\n", 23 | "print \"TYPE CTRL+C TO EXIT\"\n", 24 | "\n", 25 | "material = block.ICE # we like sand because it is subject to gravity -- create it up high, and it will fall\n", 26 | "while True:\n", 27 | " # Get the player's current position and store the coordinates\n", 28 | " [x, y, z] = world.player.getPos()\n", 29 | " dx = random.randint(-10, 10) # somewhere nearby\n", 30 | " dz = random.randint(-10, 10) # somewhere nearby\n", 31 | " dy = random.randint(5, 15) # somewhere above!\n", 32 | " world.setBlock(x+dx, y+dy, z+dz, material)\n", 33 | " time.sleep(0.5)" 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 0 40 | } -------------------------------------------------------------------------------- /classroom-code/examples/pyramid.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import sys\n", 13 | "sys.path.append( \"~/Desktop/CoderDojo\")\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "\n", 17 | "# Connect to the Minecraft server\n", 18 | "world = minecraft.Minecraft.create()\n", 19 | "\n", 20 | "# Get the player's current position and store the coordinates\n", 21 | "[x,y,z] = world.player.getPos()\n", 22 | "\n", 23 | "# Set some variables to customize your pyramid\n", 24 | "height = 25\n", 25 | "material = block.TNT\n", 26 | "\n", 27 | "# This variable will track the current level being created inside the loop\n", 28 | "level = 1\n", 29 | "\n", 30 | "# Execute the loop, building from the top down\n", 31 | "while level <= height:\n", 32 | "\tprint level\n", 33 | "\tworld.setBlocks( x - level, height - level, z - level,\n", 34 | "\t x + level, height - level, z + level, material )\n", 35 | "\tlevel = level + 0.5;\n", 36 | "\n", 37 | "# Put the player on top of the pyramid!\n", 38 | "world.player.setPos( x, height, z )" 39 | ] 40 | } 41 | ], 42 | "metadata": {}, 43 | "nbformat": 4, 44 | "nbformat_minor": 0 45 | } -------------------------------------------------------------------------------- /classroom-code/examples/pyramid_shell.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#! /usr/bin/python\n", 12 | "import sys\n", 13 | "sys.path.append( \"~/Desktop/CoderDojo\")\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "\n", 17 | "# Connect to the Minecraft server\n", 18 | "world = minecraft.Minecraft.create()\n", 19 | "\n", 20 | "# Get the player's current position and store the coordinates\n", 21 | "[x,y,z] = world.player.getPos()\n", 22 | "#[x,y,z] = [-1011,4,-930]\n", 23 | "\n", 24 | "# Set some variables to customize your pyramid\n", 25 | "height = 25\n", 26 | "material = block.STONE_SLAB\n", 27 | "\n", 28 | "# This variable will track the current level being created inside the loop\n", 29 | "level = 1\n", 30 | "\n", 31 | "# Execute the loop, building from the top down\n", 32 | "while level <= height:\n", 33 | "\tprint level\n", 34 | "\tworld.setBlocks( x - level, height - level, z - level, x - level, height - level, z + level, material )\n", 35 | "\tworld.setBlocks( x - level, height - level, z - level, x + level, height - level, z - level, material )\n", 36 | "\tworld.setBlocks( x - level, height - level, z + level, x + level, height - level, z + level, material )\n", 37 | "\tworld.setBlocks( x + level, height - level, z - level, x + level, height - level, z + level, material )\n", 38 | "\tlevel = level + 1;\n", 39 | "\n", 40 | "# Put the player on top of the pyramid!\n", 41 | "world.player.setPos( x, height, z )" 42 | ] 43 | } 44 | ], 45 | "metadata": {}, 46 | "nbformat": 4, 47 | "nbformat_minor": 0 48 | } -------------------------------------------------------------------------------- /classroom-code/examples/snowbound_flatmap.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "\n", 14 | "# mcpipy.com retrieved from URL below, written by snowbound\n", 15 | "# http://www.minecraftforum.net/topic/1680160-simple-flatmap-script/\n", 16 | "\n", 17 | "\n", 18 | "import sys\n", 19 | "import mcpi.minecraft as minecraft\n", 20 | "import mcpi.block as block\n", 21 | "\n", 22 | "\n", 23 | "mc = minecraft.Minecraft.create()\n", 24 | "mc.setBlocks(-128,0,-128,128,64,128,0)\n", 25 | "if(len(sys.argv) > 1):\n", 26 | " bid = int(sys.argv[1])\n", 27 | "else:\n", 28 | " bid = block.SANDSTONE.id\n", 29 | "\n", 30 | "if bid < 0 or bid > 108:\n", 31 | " bid = block.SANDSTONE.id\n", 32 | "\n", 33 | "mc.setBlocks(-128,0,-128,128,-64,128,bid)" 34 | ] 35 | } 36 | ], 37 | "metadata": {}, 38 | "nbformat": 4, 39 | "nbformat_minor": 0 40 | } -------------------------------------------------------------------------------- /classroom-code/examples/sphere.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import sys\n", 13 | "sys.path.append( \"~/Desktop/CoderDojo\")\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "\n", 17 | "# Connect to the Minecraft server\n", 18 | "world = minecraft.Minecraft.create()\n", 19 | "[x0,y0,z0] = world.player.getPos()\n", 20 | "y0=y0+60\n", 21 | "#y0=y0+r+r\n", 22 | "\n", 23 | "r=20\n", 24 | "material = block.GLOWING_OBSIDIAN\n", 25 | "for x in range(-r,r):\n", 26 | " for y in range(-r,r):\n", 27 | " for z in range(-r,r):\n", 28 | " if x**2 + y**2 + z**2 < r**2:\n", 29 | " if y % 2 == 0:\n", 30 | " world.setBlock( x0+x, y0+y, z0+z, material );" 31 | ] 32 | } 33 | ], 34 | "metadata": {}, 35 | "nbformat": 4, 36 | "nbformat_minor": 0 37 | } -------------------------------------------------------------------------------- /classroom-code/examples/sphere_hollow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import sys\n", 13 | "sys.path.append( \"~/Desktop/CoderDojo\")\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "\n", 17 | "# Connect to the Minecraft server\n", 18 | "world = minecraft.Minecraft.create()\n", 19 | "# Get Steve's current position\n", 20 | "[x0,y0,z0] = world.player.getPos()\n", 21 | "\n", 22 | "# Set the radius of the sphere\n", 23 | "r=20\n", 24 | "material = block.WOOD\n", 25 | "\n", 26 | "# Put the bottom edge of the sphere 8 blocks above Steve's head\n", 27 | "y0=y0+r+8\n", 28 | "\n", 29 | "for x in range(-r,r):\n", 30 | " for y in range(-r,r):\n", 31 | " for z in range(-r,r):\n", 32 | "\t # If we were making a cube, we'd put a block here\n", 33 | " candidate_location = x**2 + y**2 + z**2\n", 34 | "\t # But we're not, so if this falls outside of the sphere or wholly inside of it, skip this iteration\n", 35 | " if candidate_location < r**2 and candidate_location > (r-1)**2:\n", 36 | "\t\t# This location qualifies, so put a block here\n", 37 | " world.setBlock(x0+x, y0+y, z0+z, material);\n", 38 | "\n", 39 | "print \"Hollow sphere built successfully! Return to the game and look above you.\"\n", 40 | "\n", 41 | "# Things to try:\n", 42 | "# How could we make this a solid sphere?\n", 43 | "# How could we nest a smaller sphere inside a larger one?\n", 44 | "# How could we nest a hollow sphere inside a solid block? (How about an AIR sphere inside a WOOD block?)\n", 45 | "# How could we make it a half sphere?\n", 46 | "# How could we make it so the sphere is separated into 2 halves?\n", 47 | "# How could we make the border into ribbons instead of a solid wall?" 48 | ] 49 | } 50 | ], 51 | "metadata": {}, 52 | "nbformat": 4, 53 | "nbformat_minor": 0 54 | } -------------------------------------------------------------------------------- /classroom-code/examples/stuffaboutcode_basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#www.stuffaboutcode.com\n", 14 | "#Raspberry Pi, Minecraft API - the basics\n", 15 | "\n", 16 | "# mcpipy.com retrieved from URL below, written by stuffaboutcode\n", 17 | "# http://www.stuffaboutcode.com/2013/01/raspberry-pi-minecraft-api-basics.html\n", 18 | "\n", 19 | "#import the minecraft.py module from the minecraft directory\n", 20 | "import mcpi.minecraft as minecraft\n", 21 | "#import minecraft block module\n", 22 | "import mcpi.block as block\n", 23 | "#import time, so delays can be used\n", 24 | "import time\n", 25 | "\n", 26 | "\n", 27 | "if __name__ == \"__main__\":\n", 28 | " \n", 29 | " time.sleep(2)\n", 30 | "\n", 31 | " #Connect to minecraft by creating the minecraft object\n", 32 | " # - minecraft needs to be running and in a game\n", 33 | " mc = minecraft.Minecraft.create()\n", 34 | "\n", 35 | " #Post a message to the minecraft chat window\n", 36 | " mc.postToChat(\"Hi, Minecraft API, the basics, what can you do? \")\n", 37 | "\n", 38 | " time.sleep(5)\n", 39 | "\n", 40 | " #Find out your players position\n", 41 | " playerPos = mc.player.getPos()\n", 42 | " mc.postToChat(\"Find your position - its x=\" + str(playerPos.x) + \", y=\" + str(playerPos.y) + \", z=\" + str(playerPos.z))\n", 43 | "\n", 44 | " time.sleep(5)\n", 45 | "\n", 46 | " #Using your players position\n", 47 | " # - the players position is an x,y,z coordinate of floats (e.g. 23.59,12.00,-45.32)\n", 48 | " # - in order to use the players position in other commands we need integers (e.g. 23,12,-45)\n", 49 | " # - so round the players position\n", 50 | " # - the Vec3 object is part of the minecraft class library\n", 51 | " playerPos = minecraft.Vec3(int(playerPos.x), int(playerPos.y), int(playerPos.z))\n", 52 | "\n", 53 | " #Changing your players position\n", 54 | " mc.postToChat(\"Move your player - 30 blocks UP!\")\n", 55 | " time.sleep(2)\n", 56 | " mc.player.setPos(playerPos.x,playerPos.y + 30,playerPos.z)\n", 57 | " # - wait for you to fall!\n", 58 | " time.sleep(5)\n", 59 | "\n", 60 | " #Interacting with a block\n", 61 | " # - get the type block directly below you\n", 62 | " blockType = mc.getBlock(playerPos.x,playerPos.y - 1,playerPos.z)\n", 63 | " mc.postToChat(\"Interact with blocks - the block below you is of type - \" + str(blockType))\n", 64 | "\n", 65 | " time.sleep(5)\n", 66 | "\n", 67 | " # - change the block below you to wood planks\n", 68 | " mc.setBlock(playerPos.x,playerPos.y-1,playerPos.z,block.WOOD_PLANKS)\n", 69 | " mc.postToChat(\"Change blocks - the block below you is now wood planks\")\n", 70 | "\n", 71 | " time.sleep(5)\n", 72 | "\n", 73 | " #Creating many blocks\n", 74 | " mc.postToChat(\"Create blocks - making a diamond tower\")\n", 75 | "\n", 76 | " # - loop 20 times\n", 77 | " for up in range(0, 20):\n", 78 | " mc.setBlock(playerPos.x + 1, playerPos.y + up, playerPos.z, block.DIAMOND_BLOCK)\n", 79 | "\n", 80 | " time.sleep(2)\n", 81 | "\n", 82 | " # - put you on top of the tower\n", 83 | " mc.postToChat(\"Dont look down, because Im putting you on top of it!\")\n", 84 | " time.sleep(1)\n", 85 | " mc.player.setPos(playerPos.x + 1, playerPos.y + 20, playerPos.z)\n", 86 | "\n", 87 | " time.sleep(5)\n", 88 | "\n", 89 | " mc.postToChat(\"www.stuffaboutcode.com\")" 90 | ] 91 | } 92 | ], 93 | "metadata": {}, 94 | "nbformat": 4, 95 | "nbformat_minor": 0 96 | } -------------------------------------------------------------------------------- /classroom-code/examples/stuffaboutcode_bridge.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#www.stuffaboutcode.com\n", 14 | "#Raspberry Pi, Minecraft - auto bridge\n", 15 | "\n", 16 | "# mcpipy.com retrieved from URL below, written by stuffaboutcode\n", 17 | "# http://www.stuffaboutcode.com/2013/02/raspberry-pi-minecraft-auto-bridge.html\n", 18 | "\n", 19 | "#import the minecraft.py module from the minecraft directory\n", 20 | "import mcpi.minecraft as minecraft\n", 21 | "#import minecraft block module\n", 22 | "import mcpi.block as block\n", 23 | "#import time, so delays can be used\n", 24 | "import time\n", 25 | "\n", 26 | "\n", 27 | "#function to round players float position to integer position\n", 28 | "def roundVec3(vec3):\n", 29 | " return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))\n", 30 | "\n", 31 | "if __name__ == \"__main__\":\n", 32 | "\n", 33 | " time.sleep(2)\n", 34 | "\n", 35 | " #Connect to minecraft by creating the minecraft object\n", 36 | " # - minecraft needs to be running and in a game\n", 37 | " mc = minecraft.Minecraft.create()\n", 38 | "\n", 39 | " #Post a message to the minecraft chat window\n", 40 | " mc.postToChat(\"Hi, Minecraft - Auto Bridge Active\")\n", 41 | " mc.postToChat(\"www.stuffaboutcode.com\")\n", 42 | "\n", 43 | " #Get the players position\n", 44 | " lastPlayerPos = mc.player.getPos()\n", 45 | "\n", 46 | " while (True):\n", 47 | "\n", 48 | " #Get the players position\n", 49 | " playerPos = mc.player.getPos()\n", 50 | " \tmc.postToChat( mc.player.getPos() )\n", 51 | "\n", 52 | " #Find the difference between the player's position and the last position\n", 53 | " movementX = lastPlayerPos.x - playerPos.x\n", 54 | " movementZ = lastPlayerPos.z - playerPos.z\n", 55 | "\n", 56 | " #Has the player moved more than 0.2 in any horizontal (x,z) direction\n", 57 | "\n", 58 | " if ((movementX < -0.2) or (movementX > 0.2) or (movementZ < -0.2) or (movementZ > 0.2)):\n", 59 | "\n", 60 | " #Project players direction forward to the next square\n", 61 | " nextPlayerPos = playerPos\n", 62 | " # keep adding the movement to the players location till the next block is found\n", 63 | " while ((int(playerPos.x) == int(nextPlayerPos.x)) and (int(playerPos.z) == int(nextPlayerPos.z))):\n", 64 | " nextPlayerPos = minecraft.Vec3(nextPlayerPos.x - movementX, nextPlayerPos.y, nextPlayerPos.z - movementZ)\n", 65 | "\n", 66 | " #Is the block below the next player pos air, if so fill it in with DIAMOND\n", 67 | " blockBelowPos = roundVec3(nextPlayerPos)\n", 68 | " blockBelowPos.z = blockBelowPos.z - 1\n", 69 | " blockBelowPos.y = blockBelowPos.y - 1\n", 70 | " if mc.getBlock(blockBelowPos) == block.AIR:\n", 71 | " mc.setBlock(blockBelowPos.x, blockBelowPos.y, blockBelowPos.z, block.DIAMOND_BLOCK)\n", 72 | "\n", 73 | " #Store players last position\n", 74 | " lastPlayerPos = playerPos\n", 75 | "\n", 76 | " #Delay\n", 77 | " time.sleep(0.01)" 78 | ] 79 | } 80 | ], 81 | "metadata": {}, 82 | "nbformat": 4, 83 | "nbformat_minor": 0 84 | } -------------------------------------------------------------------------------- /classroom-code/examples/stuffaboutcode_hideandseek.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#www.stuffaboutcode.com\n", 14 | "#Raspberry Pi, Minecraft - hide and seek\n", 15 | "\n", 16 | "# mcpipy.com retrieved from URL below, written by stuffaboutcode\n", 17 | "# http://www.stuffaboutcode.com/2013/01/raspberry-pi-minecraft-hide-and-seek.html\n", 18 | "\n", 19 | "#import the minecraft.py module from the minecraft directory\n", 20 | "import mcpi.minecraft as minecraft\n", 21 | "#import minecraft block module\n", 22 | "import mcpi.block as block\n", 23 | "#import time, so delays can be used\n", 24 | "import time\n", 25 | "#import random module to create random number\n", 26 | "import random\n", 27 | "#import math module to use square root function\n", 28 | "import math\n", 29 | "\n", 30 | "\n", 31 | "#function to round players float position to integer position\n", 32 | "def roundVec3(vec3):\n", 33 | " return minecraft.Vec3(int(vec3.x), int(vec3.y), int(vec3.z))\n", 34 | "\n", 35 | "def distanceBetweenPoints(point1, point2):\n", 36 | " xd = point2.x - point1.x\n", 37 | " yd = point2.y - point1.y\n", 38 | " zd = point2.z - point1.z\n", 39 | " return math.sqrt((xd*xd) + (yd*yd) + (zd*zd))\n", 40 | " \n", 41 | "if __name__ == \"__main__\":\n", 42 | "\n", 43 | " #Connect to minecraft by creating the minecraft object\n", 44 | " # - minecraft needs to be running and in a game\n", 45 | " mc = minecraft.Minecraft.create()\n", 46 | "\n", 47 | " #Post a message to the minecraft chat window\n", 48 | " mc.postToChat(\"Hi, Minecraft Hide & Seek\")\n", 49 | "\n", 50 | " time.sleep(2)\n", 51 | " \n", 52 | " #Find the players position\n", 53 | " playerPos = mc.player.getPos()\n", 54 | " \n", 55 | " #Create random position within 50 blocks from the player, our hidden block will go there\n", 56 | " randomBlockPos = roundVec3(playerPos)\n", 57 | " randomBlockPos.x = random.randrange(randomBlockPos.x - 50, randomBlockPos.x + 50)\n", 58 | " randomBlockPos.y = random.randrange(randomBlockPos.y - 5, randomBlockPos.y + 5)\n", 59 | " randomBlockPos.z = random.randrange(randomBlockPos.z - 50, randomBlockPos.z + 50)\n", 60 | " print randomBlockPos\n", 61 | " \n", 62 | " #Create hidden diamond block\n", 63 | " mc.setBlock(randomBlockPos.x, randomBlockPos.y, randomBlockPos.z, block.DIAMOND_BLOCK)\n", 64 | " mc.postToChat(\"A diamond has been hidden - go find!\")\n", 65 | " \n", 66 | " #Start hide and seek\n", 67 | " seeking = True\n", 68 | " lastPlayerPos = playerPos\n", 69 | " lastDistanceFromBlock = distanceBetweenPoints(randomBlockPos, lastPlayerPos)\n", 70 | " timeStarted = time.time()\n", 71 | " while (seeking == True):\n", 72 | " #Get players position\n", 73 | " playerPos = mc.player.getPos()\n", 74 | " #Has the player moved\n", 75 | " if lastPlayerPos != playerPos:\n", 76 | " #print \"lastDistanceFromBlock = \" + str(lastDistanceFromBlock)\n", 77 | " distanceFromBlock = distanceBetweenPoints(randomBlockPos, playerPos)\n", 78 | " #print \"distanceFromBlock = \" + str(distanceFromBlock)\n", 79 | " if distanceFromBlock < 2:\n", 80 | " #found it!\n", 81 | " seeking = False\n", 82 | " else:\n", 83 | " if distanceFromBlock < lastDistanceFromBlock:\n", 84 | " mc.postToChat(\"Warmer \" + str(int(distanceFromBlock)) + \" blocks away\")\n", 85 | " if distanceFromBlock > lastDistanceFromBlock:\n", 86 | " mc.postToChat(\"Colder \" + str(int(distanceFromBlock)) + \" blocks away\")\n", 87 | " \n", 88 | " lastDistanceFromBlock = distanceFromBlock\n", 89 | " \n", 90 | " time.sleep(2)\n", 91 | " timeTaken = time.time() - timeStarted\n", 92 | " mc.postToChat(\"Well done - \" + str(int(timeTaken)) + \" seconds to find the diamond\")\n", 93 | "\n", 94 | " time.sleep(5)\n", 95 | " \n", 96 | " mc.postToChat(\"www.stuffaboutcode.com\")" 97 | ] 98 | } 99 | ], 100 | "metadata": {}, 101 | "nbformat": 4, 102 | "nbformat_minor": 0 103 | } -------------------------------------------------------------------------------- /classroom-code/examples/tnt.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import mcpi.minecraft\n", 13 | "import time\n", 14 | "\n", 15 | "mc = mcpi.minecraft.Minecraft.create();\n", 16 | "\n", 17 | "while True:\n", 18 | " hits = mc.events.pollBlockHits()\n", 19 | " for hit in hits:\n", 20 | " block = mc.getBlockWithData(hit.pos.x, hit.pos.y, hit.pos.z);\n", 21 | " block.data = (block.data + 1) & 0xf;\n", 22 | " mc.setBlock(hit.pos.x, hit.pos.y, hit.pos.z, block.id, block.data)\n", 23 | " mc.postToChat(\"Block data is now \" + str(block.data))\n", 24 | " time.sleep(0.1)" 25 | ] 26 | } 27 | ], 28 | "metadata": {}, 29 | "nbformat": 4, 30 | "nbformat_minor": 0 31 | } -------------------------------------------------------------------------------- /classroom-code/examples/tower.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import sys\n", 13 | "import mcpi.minecraft as minecraft\n", 14 | "import mcpi.block as block\n", 15 | "\n", 16 | "# Connect to the Minecraft server\n", 17 | "world = minecraft.Minecraft.create() \n", 18 | "# Get the player's current position and store the coordinates\n", 19 | "[x,y,z] = world.player.getPos()\n", 20 | "\n", 21 | "# Set some variables to customize your tower\n", 22 | "height = 10\n", 23 | "material = block.TNT\n", 24 | "length = \n", 25 | "\n", 26 | "level = 0\n", 27 | "keep_building = True\n", 28 | "\n", 29 | "for n in range (0,length):\n", 30 | " for p in range(0,height):\n", 31 | " world.setBlock( x+n, y+p, z, material )\n", 32 | "\n", 33 | "\n", 34 | "# Put the player on top of the tower\n", 35 | "world.player.setPos( x, height, z )" 36 | ] 37 | } 38 | ], 39 | "metadata": {}, 40 | "nbformat": 4, 41 | "nbformat_minor": 0 42 | } -------------------------------------------------------------------------------- /classroom-code/examples/tower2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/python\n", 12 | "import sys\n", 13 | "sys.path.append( \"~/Desktop/CoderDojo\")\n", 14 | "import mcpi.minecraft as minecraft\n", 15 | "import mcpi.block as block\n", 16 | "\n", 17 | "# Connect to the Minecraft server\n", 18 | "world = minecraft.Minecraft.create()\n", 19 | "\n", 20 | "# Get the player's current position and store the coordinates\n", 21 | "[x,y,z] = world.player.getPos()\n", 22 | "\n", 23 | "# Set some variables to customize your tower\n", 24 | "width = 10\n", 25 | "height = 10 \n", 26 | "material = block.SANDSTONE\n", 27 | "\n", 28 | "# Execute the loop, building from the bottom up\n", 29 | "for column in range( 0, width ):\n", 30 | "\tfor level in range( 0, height ):\n", 31 | "\t\tworld.setBlock( x+column, level, z, material )\n", 32 | "\n", 33 | "# Put the player on top of the tower\n", 34 | "world.player.setPos( x, height, z )" 35 | ] 36 | } 37 | ], 38 | "metadata": {}, 39 | "nbformat": 4, 40 | "nbformat_minor": 0 41 | } -------------------------------------------------------------------------------- /classroom-code/examples/zhuowei_rainbow.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#!/usr/bin/env python\n", 12 | "\n", 13 | "#\n", 14 | "# mcpipy.com retrieved from URL below, written by zhuowei\n", 15 | "# http://www.minecraftforum.net/topic/1638036-my-first-script-for-minecraft-pi-api-a-rainbow/\n", 16 | "\n", 17 | "import mcpi.minecraft as minecraft\n", 18 | "import mcpi.block as block\n", 19 | "from math import *\n", 20 | "\n", 21 | "colors = [14, 1, 4, 5, 3, 11, 10]\n", 22 | "\n", 23 | "mc = minecraft.Minecraft.create()\n", 24 | "height = 64\n", 25 | "\n", 26 | "mc.player.setPos( 0, height, height )\n", 27 | "\n", 28 | "mc.setBlocks(-(height*2),0,0,(height*2),height + len(colors),0,0)\n", 29 | "for x in range(0, 128):\n", 30 | " for colourindex in range(0, len(colors)):\n", 31 | " y = sin((x / (height*2.0)) * pi) * height + colourindex\n", 32 | " mc.setBlock(x - (height*2), int(y), 0, block.WOOL.id, colors[len(colors) - 1 - colourindex])" 33 | ] 34 | } 35 | ], 36 | "metadata": {}, 37 | "nbformat": 4, 38 | "nbformat_minor": 0 39 | } -------------------------------------------------------------------------------- /classroom-code/exercises/Exercise 0 -- Where are we? What are we doing?.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Introduction to our environment\n", 8 | "\n", 9 | "This notebook document gives you an introduction to the environment we will use during today's session.\n", 10 | "\n", 11 | "\n", 12 | "## Where are we?\n", 13 | "\n", 14 | "As you are working in our lab environment, there are a couple of different computers involved. The diagram below shows the programs running on each computer, so you can understand what runs where:\n", 15 | "\n", 16 | "![The Lab Programming Environment](images/programming-environment.png)\n", 17 | "\n", 18 | "As you can see in the diagram above, you have your laptop itself, which is running the Minecraft game and a web browser.\n", 19 | "\n", 20 | "The Minecraft game on your laptop talks across the network to a computer named `python.coderdojotc.org`. On that computer, inside a container shown here as *Student Instance 1*, there is a program called the *Canary Server*. The Canary Server is an instance of the Minecraft game that hosts a multi-player server.\n", 21 | "\n", 22 | "Also on that server is a program called the *Jupyter Notebook Server*. The Jupyter Notebook Server acts as a web server, so you can connect to it with a web browser. It displays *notebooks*, which are contained in files on the server.\n", 23 | "\n", 24 | "\n", 25 | "## What are we doing?\n", 26 | "\n", 27 | "In today's class, we will run Python programs inside the notebooks on the Jupyter Notebook Server. When you open a notebook and tell it to run using the *Cell* menu at the top of each page, the Jupyter Notebook Server will run the Python code it finds. When this code runs, it can talk across the local network to the Canary Server. This is how Python can make changes inside the Minecraft world. You can see the effects of these changes inside the Minecraft game on your laptop, which is also connected to the canary Server.\n", 28 | "\n", 29 | "\n", 30 | "## Next Steps\n", 31 | "\n", 32 | "Close this notebook with the *File --> Close and Halt* command. Open the next exercise, where you will run your first Python program." 33 | ] 34 | } 35 | ], 36 | "metadata": { 37 | "kernelspec": { 38 | "display_name": "Python 2", 39 | "language": "python", 40 | "name": "python2" 41 | }, 42 | "language_info": { 43 | "codemirror_mode": { 44 | "name": "ipython", 45 | "version": 2 46 | }, 47 | "file_extension": ".py", 48 | "mimetype": "text/x-python", 49 | "name": "python", 50 | "nbconvert_exporter": "python", 51 | "pygments_lexer": "ipython2", 52 | "version": "2.7.6" 53 | } 54 | }, 55 | "nbformat": 4, 56 | "nbformat_minor": 0 57 | } 58 | -------------------------------------------------------------------------------- /classroom-code/exercises/Exercise 1 -- Hello World.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Hello World!" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "The `Hello World` program is the first one you will write, in every environment, in any language!\n", 15 | "\n", 16 | "Click into the code cell below so that it is surrounded by a box. Then press the \"play\" button in the toolbar above, the one that looks like a triangle. It will run the code." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": { 23 | "collapsed": false 24 | }, 25 | "outputs": [], 26 | "source": [ 27 | "# The first step is to import the parts of code that let our Python \n", 28 | "# program talk to Minecraft:\n", 29 | "\n", 30 | "import mcpi.minecraft as minecraft\n", 31 | "import mcpi.block as block\n", 32 | "\n", 33 | "# Next, we create an object named `world`. This object is what we \n", 34 | "# use to talk to the Minecraft server.\n", 35 | "world = minecraft.Minecraft.create()\n", 36 | "\n", 37 | "# And then we post a message to chat\n", 38 | "world.postToChat(\"Hello Minecraft!\")" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "Now, switch back to your Minecraft game and open the \"chat\" by pressing the \"T\" key. Check if you see the \"`Hello Minecraft!`\" message we sent from Python. If you don't see it, click into the code cell above and press the \"play\" button again. Sometimes the chat message won't appear if you weren't connected to the game when the script was run." 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## Advanced Exercises and Questions" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "1. Can you add your name to the \"Hello Minecraft\" message?\n", 60 | "1. Can you make it say several things, on different lines?" 61 | ] 62 | } 63 | ], 64 | "metadata": { 65 | "kernelspec": { 66 | "display_name": "Python 2", 67 | "language": "python", 68 | "name": "python2" 69 | }, 70 | "language_info": { 71 | "codemirror_mode": { 72 | "name": "ipython", 73 | "version": 2 74 | }, 75 | "file_extension": ".py", 76 | "mimetype": "text/x-python", 77 | "name": "python", 78 | "nbconvert_exporter": "python", 79 | "pygments_lexer": "ipython2", 80 | "version": "2.7.6" 81 | } 82 | }, 83 | "nbformat": 4, 84 | "nbformat_minor": 0 85 | } 86 | -------------------------------------------------------------------------------- /classroom-code/exercises/Exercise 5 -- Minecraft changes trigger activity in Python.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Trigger code in Python from Minecraft" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "To find out what is happening in the Minecraft world, Python can ask via the API. The `pollBlockHits()` method will return data about each block hit with a sword since the last time it was called. **Note: You must use a sword, and you must Right-Click. This is the only action detected by this function.**" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "Like in other exercises, we need to bring in some libraries of code that enable Python to speak to Minecraft." 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "import mcpi.minecraft as minecraft\n", 33 | "import mcpi.block as block\n", 34 | "import time" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "Connect to the Minecraft server, store the connection in a variable named `world`:" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": { 48 | "collapsed": false 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "world = minecraft.Minecraft.create()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "This script works best with blocks that change appearance when their block data changes. One good example is wool, so let's create a small field of wool for you to hit with the sword:" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": { 66 | "collapsed": false 67 | }, 68 | "outputs": [], 69 | "source": [ 70 | "[x,y,z] = world.player.getPos()\n", 71 | "world.setBlocks(x,y-1,z,x+10,y-1,z+10, block.WOOL)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "Start looping forever. This is an example of a game loop, because it keeps on processsing until it is interrupted. If you want to stop the loop, press the \"stop\" button, or use the **Kernel -> Interrupt** option in the notebook menubar." 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": null, 84 | "metadata": { 85 | "collapsed": false 86 | }, 87 | "outputs": [], 88 | "source": [ 89 | "while True:\n", 90 | " hits = world.events.pollBlockHits()\n", 91 | " for hit in hits:\n", 92 | " print \"Have hit {h.x},{h.y},{h.z}\".format(h=hit.pos)\n", 93 | " block = world.getBlockWithData(hit.pos.x, hit.pos.y, hit.pos.z)\n", 94 | " block.data = (block.data + 1) & 0xf ## The & 0xf keeps the block data value below 16 (0xf in hexadecimal)\n", 95 | " world.setBlock(hit.pos.x, hit.pos.y, hit.pos.z, block.id, block.data)\n", 96 | " world.postToChat(\"Block data is now \" + str(block.data))\n", 97 | " time.sleep(1)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "The block of code above is more interesting with blocks that change based on their `data` value, such as wool, flowers, and wood. Wool changes color with the different data values." 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "## Advanced Exercises and Questions" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "1. What other block types change their appearance when you hit them with a sword while this script is running?\n", 119 | "1. Can you draw a creeper with just this code and a sword?" 120 | ] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 2", 126 | "language": "python", 127 | "name": "python2" 128 | }, 129 | "language_info": { 130 | "codemirror_mode": { 131 | "name": "ipython", 132 | "version": 2 133 | }, 134 | "file_extension": ".py", 135 | "mimetype": "text/x-python", 136 | "name": "python", 137 | "nbconvert_exporter": "python", 138 | "pygments_lexer": "ipython2", 139 | "version": "2.7.6" 140 | } 141 | }, 142 | "nbformat": 4, 143 | "nbformat_minor": 0 144 | } 145 | -------------------------------------------------------------------------------- /classroom-code/exercises/images/programming-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/classroom-code/exercises/images/programming-environment.png -------------------------------------------------------------------------------- /classroom-code/turtle-examples/3dfractaltree.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "def tree(branchLen,t):\n", 16 | " if branchLen > 6:\n", 17 | " if branchLen > 10:\n", 18 | " t.penblock(block.WOOD)\n", 19 | " else:\n", 20 | " t.penblock(block.LEAVES)\n", 21 | "\n", 22 | " #for performance\n", 23 | " x,y,z = t.position.x, t.position.y, t.position.z\n", 24 | " #draw branch\n", 25 | " t.forward(branchLen)\n", 26 | " \n", 27 | " t.up(20)\n", 28 | " tree(branchLen-2, t)\n", 29 | " \n", 30 | " t.right(90)\n", 31 | " tree(branchLen-2, t)\n", 32 | "\n", 33 | " t.left(180)\n", 34 | " tree(branchLen-2, t)\n", 35 | "\n", 36 | " t.down(40)\n", 37 | " t.right(90)\n", 38 | " tree(branchLen-2, t)\n", 39 | "\n", 40 | " t.up(20)\n", 41 | " \n", 42 | " #go back\n", 43 | " #t.backward(branchLen)\n", 44 | " #for performance - rather than going back over every line\n", 45 | " t.setposition(x, y, z)\n", 46 | "\n", 47 | "#create connection to minecraft\n", 48 | "mc = minecraft.Minecraft.create()\n", 49 | "\n", 50 | "#get players position\n", 51 | "pos = mc.player.getPos()\n", 52 | "\n", 53 | "#create minecraft turtle\n", 54 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 55 | "\n", 56 | "#point up\n", 57 | "steve.setverticalheading(90)\n", 58 | "\n", 59 | "#set speed\n", 60 | "steve.speed(0)\n", 61 | "\n", 62 | "#call the tree fractal\n", 63 | "tree(20, steve)" 64 | ] 65 | } 66 | ], 67 | "metadata": { 68 | "kernelspec": { 69 | "display_name": "Python 2", 70 | "language": "python", 71 | "name": "python2" 72 | }, 73 | "language_info": { 74 | "codemirror_mode": { 75 | "name": "ipython", 76 | "version": 2 77 | }, 78 | "file_extension": ".py", 79 | "mimetype": "text/x-python", 80 | "name": "python", 81 | "nbconvert_exporter": "python", 82 | "pygments_lexer": "ipython2", 83 | "version": "2.7.6" 84 | } 85 | }, 86 | "nbformat": 4, 87 | "nbformat_minor": 0 88 | } 89 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/3dfractaltree_colors.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "import random\n", 15 | "\n", 16 | "def tree(branchLen,t):\n", 17 | " if branchLen > 6:\n", 18 | " t.penblock(block.WOOL.id, random.randint(0,15))\n", 19 | " \n", 20 | " #for performance\n", 21 | " x,y,z = t.position.x, t.position.y, t.position.z\n", 22 | " #draw branch\n", 23 | " t.forward(branchLen)\n", 24 | " \n", 25 | " t.up(20)\n", 26 | " tree(branchLen-2, t)\n", 27 | " \n", 28 | " t.right(90)\n", 29 | " tree(branchLen-2, t)\n", 30 | "\n", 31 | " t.left(180)\n", 32 | " tree(branchLen-2, t)\n", 33 | "\n", 34 | " t.down(40)\n", 35 | " t.right(90)\n", 36 | " tree(branchLen-2, t)\n", 37 | "\n", 38 | " t.up(20)\n", 39 | " \n", 40 | " #go back\n", 41 | " #t.backward(branchLen)\n", 42 | " #for performance - rather than going back over every line\n", 43 | " t.setposition(x, y, z)\n", 44 | "\n", 45 | "#create connection to minecraft\n", 46 | "mc = minecraft.Minecraft.create()\n", 47 | "\n", 48 | "#get players position\n", 49 | "pos = mc.player.getPos()\n", 50 | "\n", 51 | "#create minecraft turtle\n", 52 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 53 | "\n", 54 | "#point up\n", 55 | "steve.setverticalheading(90)\n", 56 | "\n", 57 | "#set speed\n", 58 | "steve.speed(0)\n", 59 | "\n", 60 | "#call the tree fractal\n", 61 | "tree(20, steve)" 62 | ] 63 | } 64 | ], 65 | "metadata": { 66 | "kernelspec": { 67 | "display_name": "Python 2", 68 | "language": "python", 69 | "name": "python2" 70 | }, 71 | "language_info": { 72 | "codemirror_mode": { 73 | "name": "ipython", 74 | "version": 2 75 | }, 76 | "file_extension": ".py", 77 | "mimetype": "text/x-python", 78 | "name": "python", 79 | "nbconvert_exporter": "python", 80 | "pygments_lexer": "ipython2", 81 | "version": "2.7.6" 82 | } 83 | }, 84 | "nbformat": 4, 85 | "nbformat_minor": 0 86 | } 87 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/3dnautilus.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "#create connection to minecraft\n", 16 | "mc = minecraft.Minecraft.create()\n", 17 | "\n", 18 | "#get players position\n", 19 | "pos = mc.player.getPos()\n", 20 | "\n", 21 | "#create minecraft turtle\n", 22 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 23 | "\n", 24 | "steve.speed(0)\n", 25 | "steve.penblock(block.WOOL.id, 14)\n", 26 | "S = 50\n", 27 | "for j in range(0, 20):\n", 28 | " steve.up(j*10)\n", 29 | " steve.forward(S)\n", 30 | " \n", 31 | " steve.left(90)\n", 32 | " steve.down(j*10)\n", 33 | " steve.forward(S)\n", 34 | "\n", 35 | " steve.left(90)\n", 36 | " steve.down(j*10)\n", 37 | " steve.forward(S)\n", 38 | "\n", 39 | " steve.left(90)\n", 40 | " steve.up(j*10)\n", 41 | " steve.forward(S)\n", 42 | " steve.left(90)\n", 43 | "\n", 44 | " steve.left(10)\n", 45 | " S = 0.9*S" 46 | ] 47 | } 48 | ], 49 | "metadata": { 50 | "kernelspec": { 51 | "display_name": "Python 2", 52 | "language": "python", 53 | "name": "python2" 54 | }, 55 | "language_info": { 56 | "codemirror_mode": { 57 | "name": "ipython", 58 | "version": 2 59 | }, 60 | "file_extension": ".py", 61 | "mimetype": "text/x-python", 62 | "name": "python", 63 | "nbconvert_exporter": "python", 64 | "pygments_lexer": "ipython2", 65 | "version": "2.7.6" 66 | } 67 | }, 68 | "nbformat": 4, 69 | "nbformat_minor": 0 70 | } 71 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining 2 | a copy of this software and associated documentation files (the 3 | "Software"), to deal in the Software without restriction, including 4 | without limitation the rights to use, copy, modify, merge, publish, 5 | distribute, sublicense, and/or sell copies of the Software, and to 6 | permit persons to whom the Software is furnished to do so, subject to 7 | the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be 10 | included in all copies or substantial portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 13 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 14 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 16 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 17 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/README-minecraft-turtle.md: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Minecraft - Turtle Library 3 | Martin O'Hanlon (martin@ohanlonweb.com) 4 | http://www.stuffaboutcode.com 5 | http://www.stuffaboutcode.com/2014/05/minecraft-graphics-turtle.html 6 | ------------------------------------------------------------------------------- 7 | A 3d grapics turtle for Minecraft: Pi edition. 8 | ------------------------------------------------------------------------------ 9 | 10 | Version history 11 | 0.1 - first beta release 12 | 0.2 - bug fixes, new examples 13 | 14 | ------------------------------------------------------------------------------- 15 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/adventuresinrpi.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "#Ported from the scratch turtle project in \"Adventures in Raspberry Pi\"\n", 13 | "from mcpiext import minecraftturtle\n", 14 | "from mcpi import minecraft, block\n", 15 | "\n", 16 | "#create connection to minecraft\n", 17 | "mc = minecraft.Minecraft.create()\n", 18 | "\n", 19 | "#get players position\n", 20 | "pos = mc.player.getPos()\n", 21 | "\n", 22 | "#create minecraft turtle\n", 23 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 24 | "steve.speed(0)\n", 25 | "steve.setheading(90)\n", 26 | "NumberOfSides = 5\n", 27 | "Angle = 360 / NumberOfSides\n", 28 | "SideLength = 20\n", 29 | "WoolColour = 0\n", 30 | "\n", 31 | "for count in range(24):\n", 32 | " for side in range(NumberOfSides):\n", 33 | " steve.forward(SideLength)\n", 34 | " steve.right(Angle)\n", 35 | " steve.right(15)\n", 36 | " WoolColour += 1\n", 37 | " if WoolColour > 15: WoolColour = 0\n", 38 | " steve.penblock(block.WOOL.id, WoolColour)\n", 39 | " #go 3d\n", 40 | " #steve.sety(steve.position.y + 1)" 41 | ] 42 | } 43 | ], 44 | "metadata": { 45 | "kernelspec": { 46 | "display_name": "Python 2", 47 | "language": "python", 48 | "name": "python2" 49 | }, 50 | "language_info": { 51 | "codemirror_mode": { 52 | "name": "ipython", 53 | "version": 2 54 | }, 55 | "file_extension": ".py", 56 | "mimetype": "text/x-python", 57 | "name": "python", 58 | "nbconvert_exporter": "python", 59 | "pygments_lexer": "ipython2", 60 | "version": "2.7.6" 61 | } 62 | }, 63 | "nbformat": 4, 64 | "nbformat_minor": 0 65 | } 66 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/circle.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example - Circle\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "#create connection to minecraft\n", 16 | "mc = minecraft.Minecraft.create()\n", 17 | "\n", 18 | "#get players position\n", 19 | "pos = mc.player.getPos()\n", 20 | "\n", 21 | "#create minecraft turtle\n", 22 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 23 | "steve.speed(10)\n", 24 | "for step in range(0,100):\n", 25 | " steve.right(5)\n", 26 | " steve.forward(2)" 27 | ] 28 | } 29 | ], 30 | "metadata": { 31 | "kernelspec": { 32 | "display_name": "Python 2", 33 | "language": "python", 34 | "name": "python2" 35 | }, 36 | "language_info": { 37 | "codemirror_mode": { 38 | "name": "ipython", 39 | "version": 2 40 | }, 41 | "file_extension": ".py", 42 | "mimetype": "text/x-python", 43 | "name": "python", 44 | "nbconvert_exporter": "python", 45 | "pygments_lexer": "ipython2", 46 | "version": "2.7.6" 47 | } 48 | }, 49 | "nbformat": 4, 50 | "nbformat_minor": 0 51 | } 52 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/fractal.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "\n", 16 | "def f(turtle, length, depth):\n", 17 | " if depth == 0:\n", 18 | " turtle.forward(length)\n", 19 | " else:\n", 20 | " f(turtle, length/3, depth-1)\n", 21 | " turtle.right(60)\n", 22 | " f(turtle, length/3, depth-1)\n", 23 | " turtle.left(120)\n", 24 | " f(turtle, length/3, depth-1)\n", 25 | " turtle.right(60)\n", 26 | " f(turtle, length/3, depth-1)\n", 27 | "\n", 28 | "#create connection to minecraft\n", 29 | "mc = minecraft.Minecraft.create()\n", 30 | "\n", 31 | "#get players position\n", 32 | "pos = mc.player.getPos()\n", 33 | "\n", 34 | "#create minecraft turtle\n", 35 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 36 | "\n", 37 | "#set speed\n", 38 | "steve.speed(0)\n", 39 | "\n", 40 | "#fractal\n", 41 | "f(steve, 500, 6)" 42 | ] 43 | } 44 | ], 45 | "metadata": { 46 | "kernelspec": { 47 | "display_name": "Python 2", 48 | "language": "python", 49 | "name": "python2" 50 | }, 51 | "language_info": { 52 | "codemirror_mode": { 53 | "name": "ipython", 54 | "version": 2 55 | }, 56 | "file_extension": ".py", 57 | "mimetype": "text/x-python", 58 | "name": "python", 59 | "nbconvert_exporter": "python", 60 | "pygments_lexer": "ipython2", 61 | "version": "2.7.6" 62 | } 63 | }, 64 | "nbformat": 4, 65 | "nbformat_minor": 0 66 | } 67 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/fractaltree.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "def tree(branchLen,t):\n", 16 | " if branchLen > 2:\n", 17 | " t.forward(branchLen)\n", 18 | " t.up(20)\n", 19 | " tree(branchLen-2,t)\n", 20 | " t.down(40)\n", 21 | " tree(branchLen-2,t)\n", 22 | " t.up(20)\n", 23 | " t.backward(branchLen)\n", 24 | "\n", 25 | "#create connection to minecraft\n", 26 | "mc = minecraft.Minecraft.create()\n", 27 | "\n", 28 | "#get players position\n", 29 | "pos = mc.player.getPos()\n", 30 | "\n", 31 | "#create minecraft turtle\n", 32 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 33 | "\n", 34 | "#point up\n", 35 | "steve.setverticalheading(90)\n", 36 | "\n", 37 | "#set speed\n", 38 | "steve.speed(0)\n", 39 | "\n", 40 | "#call the tree fractal\n", 41 | "tree(20, steve)" 42 | ] 43 | } 44 | ], 45 | "metadata": { 46 | "kernelspec": { 47 | "display_name": "Python 2", 48 | "language": "python", 49 | "name": "python2" 50 | }, 51 | "language_info": { 52 | "codemirror_mode": { 53 | "name": "ipython", 54 | "version": 2 55 | }, 56 | "file_extension": ".py", 57 | "mimetype": "text/x-python", 58 | "name": "python", 59 | "nbconvert_exporter": "python", 60 | "pygments_lexer": "ipython2", 61 | "version": "2.7.6" 62 | } 63 | }, 64 | "nbformat": 4, 65 | "nbformat_minor": 0 66 | } 67 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/pattern.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example - Crazy Pattern\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "import random\n", 15 | "\n", 16 | "#create connection to minecraft\n", 17 | "mc = minecraft.Minecraft.create()\n", 18 | "\n", 19 | "#get players position\n", 20 | "pos = mc.player.getPos()\n", 21 | "\n", 22 | "#create minecraft turtle\n", 23 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 24 | "\n", 25 | "steve.penblock(block.WOOL.id, 11)\n", 26 | "steve.speed(10)\n", 27 | "\n", 28 | "for step in range(0,50):\n", 29 | " steve.forward(50)\n", 30 | " steve.right(123)" 31 | ] 32 | } 33 | ], 34 | "metadata": { 35 | "kernelspec": { 36 | "display_name": "Python 2", 37 | "language": "python", 38 | "name": "python2" 39 | }, 40 | "language_info": { 41 | "codemirror_mode": { 42 | "name": "ipython", 43 | "version": 2 44 | }, 45 | "file_extension": ".py", 46 | "mimetype": "text/x-python", 47 | "name": "python", 48 | "nbconvert_exporter": "python", 49 | "pygments_lexer": "ipython2", 50 | "version": "2.7.6" 51 | } 52 | }, 53 | "nbformat": 4, 54 | "nbformat_minor": 0 55 | } 56 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/spiral.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example - Spiral\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "import random\n", 15 | "\n", 16 | "#create connection to minecraft\n", 17 | "mc = minecraft.Minecraft.create()\n", 18 | "\n", 19 | "#get players position\n", 20 | "pos = mc.player.getPos()\n", 21 | "\n", 22 | "#create minecraft turtle\n", 23 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 24 | "\n", 25 | "steve.penblock(block.WOOL.id, 1)\n", 26 | "steve.speed(10)\n", 27 | "steve.up(5)\n", 28 | "\n", 29 | "for step in range(0,1000):\n", 30 | " steve.forward(2)\n", 31 | " steve.right(10)" 32 | ] 33 | } 34 | ], 35 | "metadata": { 36 | "kernelspec": { 37 | "display_name": "Python 2", 38 | "language": "python", 39 | "name": "python2" 40 | }, 41 | "language_info": { 42 | "codemirror_mode": { 43 | "name": "ipython", 44 | "version": 2 45 | }, 46 | "file_extension": ".py", 47 | "mimetype": "text/x-python", 48 | "name": "python", 49 | "nbconvert_exporter": "python", 50 | "pygments_lexer": "ipython2", 51 | "version": "2.7.6" 52 | } 53 | }, 54 | "nbformat": 4, 55 | "nbformat_minor": 0 56 | } 57 | -------------------------------------------------------------------------------- /classroom-code/turtle-examples/squares.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "#Minecraft Turtle Example\n", 12 | "from mcpiext import minecraftturtle\n", 13 | "from mcpi import minecraft, block\n", 14 | "\n", 15 | "#create connection to minecraft\n", 16 | "mc = minecraft.Minecraft.create()\n", 17 | "\n", 18 | "#get players position\n", 19 | "pos = mc.player.getPos()\n", 20 | "\n", 21 | "#create minecraft turtle\n", 22 | "steve = minecraftturtle.MinecraftTurtle(mc, pos)\n", 23 | "\n", 24 | "steve.speed(10)\n", 25 | "\n", 26 | "#draw a square\n", 27 | "steve.forward(10)\n", 28 | "steve.right(90)\n", 29 | "steve.forward(10)\n", 30 | "steve.right(90)\n", 31 | "steve.forward(10)\n", 32 | "steve.right(90)\n", 33 | "steve.forward(10)\n", 34 | "\n", 35 | "#draw a square on the floor\n", 36 | "steve.walk()\n", 37 | "steve.forward(11)\n", 38 | "steve.right(90)\n", 39 | "steve.forward(10)\n", 40 | "steve.right(90)\n", 41 | "steve.forward(10)\n", 42 | "steve.right(90)\n", 43 | "steve.forward(10)" 44 | ] 45 | } 46 | ], 47 | "metadata": { 48 | "kernelspec": { 49 | "display_name": "Python 2", 50 | "language": "python", 51 | "name": "python2" 52 | }, 53 | "language_info": { 54 | "codemirror_mode": { 55 | "name": "ipython", 56 | "version": 2 57 | }, 58 | "file_extension": ".py", 59 | "mimetype": "text/x-python", 60 | "name": "python", 61 | "nbconvert_exporter": "python", 62 | "pygments_lexer": "ipython2", 63 | "version": "2.7.6" 64 | } 65 | }, 66 | "nbformat": 4, 67 | "nbformat_minor": 0 68 | } 69 | -------------------------------------------------------------------------------- /docs/class-materials/Class Kickoff Deck.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/class-materials/Class Kickoff Deck.pdf -------------------------------------------------------------------------------- /docs/class-materials/Class Kickoff Deck.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/class-materials/Class Kickoff Deck.pptx -------------------------------------------------------------------------------- /docs/classroom/_images/coordinates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/coordinates.png -------------------------------------------------------------------------------- /docs/classroom/_images/hello-world-minecraft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/hello-world-minecraft.png -------------------------------------------------------------------------------- /docs/classroom/_images/hello-world-notebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/hello-world-notebook.png -------------------------------------------------------------------------------- /docs/classroom/_images/ipython-notebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/ipython-notebook.png -------------------------------------------------------------------------------- /docs/classroom/_images/lab-instance-connection-card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/lab-instance-connection-card.png -------------------------------------------------------------------------------- /docs/classroom/_images/minecraft-profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/minecraft-profile.png -------------------------------------------------------------------------------- /docs/classroom/_images/programming-environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/docs/classroom/_images/programming-environment.png -------------------------------------------------------------------------------- /docs/classroom/exercises.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Prepared Exercises 3 | ==================== 4 | 5 | We have a handful of exercises prepared for your exploration in the 6 | classroom. The exercises should be visible in your IPython notebook 7 | session, under the folder named :file:`exercises`. If you cannot see 8 | the :file:`exercises` folder in IPython, click on the icon of the 9 | house to navigate to the top level folder. 10 | 11 | Exercise 1: Hello World! 12 | You've probably already walked through this exercise as part of 13 | testing your environment, but later on, you might see if you can 14 | change it to do something more interesting, like saying your name 15 | or printing the current time. 16 | 17 | Exercise 2: Getting Started with IPython 18 | This exercise gets you familiar with the IPython environment. 19 | 20 | Exercise 3: Basic Python Syntax 21 | This exercise introduces you to the core syntax of the Python 22 | language. 23 | 24 | Exercise 4: Change the Minecraft world using Python 25 | This exercise helps you use Python to make changes within the 26 | Minecraft world. 27 | 28 | Exercise 5: Minecraft changes trigger activity in Python 29 | This exercise shows you how Python can detect when something has 30 | happened in the Minecraft world so it can react. 31 | -------------------------------------------------------------------------------- /docs/classroom/index.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Classroom Documentation 3 | ========================= 4 | 5 | The section contains documentation useful for participants in a 6 | CoderDojo classroom event. Visit each of the links below to find the 7 | documentation needed to get set up and then work through the classroom 8 | exercises of the *Build worlds in Minecraft with Python* code group. 9 | 10 | First, we start with an overview: 11 | 12 | .. toctree:: 13 | :maxdepth: 1 14 | 15 | overview 16 | 17 | Next, we want to be sure you have all the pieces set up to work 18 | through the exercises: 19 | 20 | .. toctree:: 21 | :maxdepth: 1 22 | 23 | setup 24 | wifi 25 | lab-instance 26 | test 27 | 28 | After you are set up, you're ready to tackle the meat of the class: 29 | 30 | .. toctree:: 31 | :maxdepth: 1 32 | 33 | exercises 34 | other-scripts 35 | your-own-thing 36 | 37 | Finally, some reference material you might need: 38 | 39 | .. toctree:: 40 | :maxdepth: 1 41 | 42 | mcpi 43 | player-controls 44 | resources 45 | -------------------------------------------------------------------------------- /docs/classroom/lab-instance.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | Connect to Your Lab Instance 3 | ============================== 4 | 5 | Once you are connected to :doc:`Wi-Fi `, you need to turn your 6 | attention to connecting your PC to the IPython Notebook and the 7 | Minecraft world in your :term:`lab instance`. The diagram below 8 | illustrates what sits where: 9 | 10 | .. image:: _images/programming-environment.png 11 | 12 | The :doc:`architecture guide <../reference/architecture>` explains a 13 | bit more about the peices in this diagram. 14 | 15 | 16 | Lab Instance Connection Card 17 | ============================ 18 | 19 | Your :term:`lab instance connection card` has all the critical 20 | information, so make sure you have it in hand, and make sure the 21 | Mentor who took your account name has had time to set up your instance 22 | on the lab server. If so, you're ready to proceed. 23 | 24 | The connection card looks something like the following: 25 | 26 | .. image:: _images/lab-instance-connection-card.png 27 | 28 | Key information found on this card: 29 | 30 | * Your Instance Number. In the upper right corner of the card is your 31 | Lab Instance Number. If you need to ask a mentor to restart your 32 | instance, they will need to know your instance number. 33 | 34 | .. note:: Too much TNT? A pyramid made out of beds or water? A 35 | restart can get you going again quickly. 36 | 37 | * The IPython URL. It looks something like 38 | ``https://python.coderdojotc.org:12356/``. Many people miss the 39 | **S** in the ``https`` part of the URL. Many other people miss the 40 | numbers that follow the domain name. Both of these are critical to 41 | connect to your instance. 42 | 43 | * The IPython password. When you first connect, you will be asked for 44 | a password to make sure only you can access the IPython notebook 45 | server in your instance. 46 | 47 | * Your Minecraft/Mojang account name. This is printed on the line that 48 | reads "Step 3: Connect to the Minecraft Server as **coderdojo##**" 49 | This is the account you should use to log into the Minecraft 50 | world. Only this account will be able to make changes in your world. 51 | 52 | * Your Minecraft server address. This looks very similar to the 53 | IPython URL, but it just contains the server name 54 | (``python.coderdojotc.org``) and a port number (the digits following 55 | the colon). 56 | 57 | 58 | Connect to the IPython Notebook 59 | =============================== 60 | 61 | The steps involved in connecting to IPython include: 62 | 63 | #. Open your web browser. You need to use Chrome, Firefox, or IE 11 or 64 | newer. Safari is known to *not work*, at least on older Macs. 65 | 66 | #. Visit the URL given on the connection card. The browser will 67 | probably complain that it doesn't trust the site. Proceed past the 68 | warnings. 69 | 70 | #. Enter the IPython password when prompted. 71 | 72 | You should see a screen like the one below: 73 | 74 | .. image:: _images/ipython-notebook.png 75 | 76 | 77 | Connect to the Minecraft Server 78 | =============================== 79 | 80 | The steps involved in connecting to Minecraft include: 81 | 82 | #. Launch Minecraft on your PC. If you haven't already installed and 83 | played Minecraft on your PC, visit the `Minecraft download page 84 | `_. Download and install the 85 | appropriate version for your operating system. 86 | 87 | #. You will need to log into Minecraft. The account name is printed on 88 | the connection card. A mentor will need to log you in. If you are 89 | working through these exercises at home, use your personal 90 | Minecraft account. 91 | 92 | #. Create a profile and make sure it uses the latest patch in the 1.8 93 | release series. For example, you can specify ``release 1.8.4`` of 94 | the game. The image below illustrates what a properly configured 95 | profile will loook like: 96 | 97 | .. image:: _images/minecraft-profile.png 98 | 99 | #. After saving the profile (if necessary), click :guilabel:`Play` to 100 | launch it. 101 | 102 | #. Choose :guilabel:`Multiplayer`, then choose :guilabel:`Direct Connect`. 103 | 104 | #. In the :guilabel:`Server Address` field, enter the Minecraft Server 105 | address from your connection card, including the port number at the 106 | end. 107 | 108 | #. Finally, click :guilabel:`Join Server`. After a brief delay, you 109 | should see your Minecraft world. 110 | 111 | 112 | Once you can talk to the IPython notebook server and the Minecraft 113 | server, you need to make sure they can talk to each other. Continue on 114 | to :doc:`test your environment `. 115 | -------------------------------------------------------------------------------- /docs/classroom/mcpi.rst: -------------------------------------------------------------------------------- 1 | =================================== 2 | Controlling Minecraft from Python 3 | =================================== 4 | 5 | Coordinate System 6 | ================= 7 | 8 | Most coordinates are in the form of a three integer vector (x,y,z) 9 | which address a specific tile in the game world. (0,0,0) is the spawn 10 | point sea level. (X,Z) is the ground plane, and Y is towards the 11 | sky. In other words, X is left and right, Z is forward and backward, 12 | and Y is up and down. 13 | 14 | .. figure:: _images/coordinates.png 15 | 16 | Minecraft's odd x-y-z coordinate system 17 | 18 | 19 | Minecraft Programming Reference 20 | =============================== 21 | 22 | These are just a few highlights. A more detailed reference can be 23 | found in the `full API reference`_. 24 | 25 | .. _full API reference: http://www.stuffaboutcode.com/p/minecraft-api-reference.html 26 | 27 | 28 | World 29 | ----- 30 | 31 | .. py:function:: world.getBlock(x, y, z) 32 | 33 | Look up the type of block at the specified coordinates. 34 | 35 | .. py:function:: world.setBlock(x, y, z, block_type) 36 | 37 | Set the block at the specified coordinates to the type block_type. 38 | 39 | .. py:function:: world.setBlocks(x1, y1, z1, x2, y2, z2, block_type) 40 | 41 | Create a set of blocks starting at one coordinate point extending 42 | to another point with blocks of the type block_type. This can be 43 | used to make cubes or rectangles. 44 | 45 | .. py:function:: world.getHeight(x, z) 46 | 47 | Look up the height (y coordinate) of the tallest brick at the 48 | specified x and y coordinates. 49 | 50 | .. py:function:: world.postToChat("Message") 51 | 52 | Send a message over chat. 53 | 54 | 55 | Player 56 | ------ 57 | 58 | .. py:function:: player.getPos() 59 | 60 | Look up the coordinates that the player is currently positioned at. 61 | 62 | .. py:function:: player.setPos(x,y,z) 63 | 64 | Set the player’s position to the specified coordinates. 65 | 66 | 67 | Blocks 68 | ------ 69 | 70 | As is the case in most things related to programming, the 71 | :file:`mcpi/block.py` `source code file`_ is the ultimate authority 72 | for which blocks are available for your use. The table below lists 73 | those constants and includes a few notes about some of the blocks. 74 | 75 | .. _source code file: https://github.com/CoderDojoTC/python-minecraft/blob/master/mcpi/block.py 76 | 77 | ======================= =================================================== 78 | Block Name Notes 79 | ======================= =================================================== 80 | ``AIR`` 81 | ``STONE`` 82 | ``GRASS`` 83 | ``DIRT`` 84 | ``COBBLESTONE`` 85 | ``WOOD_PLANKS`` Use ``block_data`` to control what kind of planks. 86 | ``SAPLING`` 87 | ``BEDROCK`` 88 | ``WATER_FLOWING`` 89 | ``WATER`` An alias for ``WATER_FLOWING`` 90 | ``WATER_STATIONARY`` 91 | ``LAVA_FLOWING`` 92 | ``LAVA`` An alias for ``LAVA_FLOWING`` 93 | ``LAVA_STATIONARY`` 94 | ``SAND`` 95 | ``GRAVEL`` 96 | ``GOLD_ORE`` 97 | ``IRON_ORE`` 98 | ``COAL_ORE`` 99 | ``WOOD`` Use ``block_data`` to control what kind of wood. 100 | ``LEAVES`` 101 | ``GLASS`` 102 | ``LAPIS_LAZULI_ORE`` 103 | ``LAPIS_LAZULI_BLOCK`` 104 | ``SANDSTONE`` 105 | ``BED`` 106 | ``COBWEB`` 107 | ``GRASS_TALL`` 108 | ``WOOL`` Use ``block_data`` to control what color wool. 109 | ``FLOWER_YELLOW`` 110 | ``FLOWER_CYAN`` 111 | ``MUSHROOM_BROWN`` 112 | ``MUSHROOM_RED`` 113 | ``GOLD_BLOCK`` 114 | ``IRON_BLOCK`` 115 | ``STONE_SLAB_DOUBLE`` 116 | ``STONE_SLAB`` 117 | ``BRICK_BLOCK`` 118 | ``TNT`` 119 | ``BOOKSHELF`` 120 | ``MOSS_STONE`` 121 | ``OBSIDIAN`` 122 | ``TORCH`` 123 | ``FIRE`` 124 | ``STAIRS_WOOD`` 125 | ``CHEST`` 126 | ``DIAMOND_ORE`` 127 | ``DIAMOND_BLOCK`` 128 | ``CRAFTING_TABLE`` 129 | ``FARMLAND`` 130 | ``FURNACE_INACTIVE`` 131 | ``FURNACE_ACTIVE`` 132 | ``DOOR_WOOD`` 133 | ``LADDER`` 134 | ``RAIL`` 135 | ``STAIRS_COBBLESTONE`` 136 | ``DOOR_IRON`` 137 | ``REDSTONE_ORE`` 138 | ``SNOW`` 139 | ``ICE`` 140 | ``SNOW_BLOCK`` 141 | ``CACTUS`` 142 | ``CLAY`` 143 | ``SUGAR_CANE`` 144 | ``FENCE`` 145 | ``GLOWSTONE_BLOCK`` 146 | ``BEDROCK_INVISIBLE`` 147 | ``STONE_BRICK`` 148 | ``GLASS_PANE`` 149 | ``MELON`` 150 | ``FENCE_GATE`` 151 | ``GLOWING_OBSIDIAN`` 152 | ``NETHER_REACTOR_CORE`` 153 | ======================= =================================================== 154 | 155 | The underlying engine actually provides all of `these block types`_. 156 | If you see one is missing from the MCPI ``block`` module, you are free 157 | to edit :file:`mcpi/block.py` to add more blocks using the decimal 158 | value listed and following the pattern you find in the existing code. 159 | 160 | .. _these block types: http://minecraft.gamepedia.com/Data_values_(Pocket_Edition) 161 | -------------------------------------------------------------------------------- /docs/classroom/other-scripts.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Other Scripts to Explore 3 | ========================== 4 | 5 | In addition to the prepared IPython exercises, your IPython instance 6 | has access to plenty of other IPython examples. The examples should be 7 | visible in your IPython notebook session, under the folder named 8 | :file:`examples`. If you cannot see the :file:`examples` folder in 9 | IPython, click on the icon of the house to navigate to the top level 10 | folder. 11 | 12 | Here are some that might be fun to play with: 13 | 14 | Simple Sripts 15 | ============= 16 | 17 | These scripts are pretty simple, and good places for beginners to 18 | start: 19 | 20 | blink 21 | ----- 22 | 23 | This simple script creates a block that flips between different 24 | block types, making it seem to blink. 25 | 26 | 27 | Moderate Sripts 28 | =============== 29 | 30 | These scripts are a step more complex. Move on to these when you are 31 | ready for a challenge. 32 | 33 | 34 | brooksc_tntsnake 35 | ---------------- 36 | 37 | This script makes a "snake" of TNT through your world. 38 | 39 | 40 | sphere 41 | ------ 42 | 43 | This script creates spherical objects in your Minecraft world. 44 | 45 | 46 | sphere_hollow 47 | ------------- 48 | 49 | This script shows you how to make spheres hollow: fill them with 50 | air. This technique comes in handy in other places, too. 51 | 52 | 53 | Advanced Sripts 54 | =============== 55 | 56 | These scripts are really complex. If you can figure these out, you are 57 | ready to make your own Mods. 58 | 59 | 60 | sleepyoz_analogclock 61 | -------------------- 62 | 63 | This script draws and animates an analog clock in your Minecraft 64 | world. Really cool. 65 | -------------------------------------------------------------------------------- /docs/classroom/overview.rst: -------------------------------------------------------------------------------- 1 | =========================== 2 | Overview of Today's Class 3 | =========================== 4 | 5 | This section describes how we normally work in the CoderDojo classroom 6 | and what to expect in today's session. 7 | 8 | 9 | Organization and Introductions 10 | ============================== 11 | 12 | We try to have around three students per mentor. After you first get 13 | settled into your seat, take a few moments to get to know the mentors 14 | and the other students sitting near you. Here are some example 15 | questions to break the ice: 16 | 17 | * What's your name? 18 | 19 | * What grade are you in? Or for mentors, what year were you last in 20 | school? 21 | 22 | * Have you attended (or mentored) this class before? 23 | 24 | * What kind of experience do you have with programming? 25 | 26 | * Why did you come to this class today? What are you hoping to do or 27 | learn? 28 | 29 | Be sure to talk to the people around you. You may have something to 30 | teach them, and they may know something you want to learn. This isn't 31 | a library, so you won't get into trouble for talking. Making friends, 32 | sharing stories, and working together are all OK. 33 | 34 | 35 | Learning Objectives 36 | =================== 37 | 38 | Here are some of the things you will learn while participating in 39 | today's class: 40 | 41 | * How to read, write, and run code in IPython 42 | 43 | * Basic Python syntax 44 | 45 | * How to change the Minecraft world using Python 46 | 47 | * How to have the Minecraft world trigger activity in Python 48 | 49 | * Anything else you want! Be sure to talk to a mentor if there is 50 | something specific you are looking to learn. 51 | 52 | 53 | Order of Events 54 | =============== 55 | 56 | Here's how things typically happen in the CoderDojo classroom: 57 | 58 | #. Get connected. This means getting your PC onto the Wi-Fi network, 59 | and then getting connected to your :term:`lab instance`. 60 | 61 | #. Work through each exercise. We have several exercises, each 62 | designed to teach you different things about the IPython notebook 63 | environment, Python programming, and interacting with Minecraft 64 | through Python code. The exercises are numbered, and it's a good 65 | idea to tackle them in order. 66 | 67 | #. Look at the other examples. See if you can understand what they do, 68 | and think about how you might want to change them. Then give it a 69 | try! 70 | 71 | 72 | Ground Rules 73 | ============ 74 | 75 | In CoderDojo, **the one rule is "be cool".** Putting this into 76 | practice in the classroom, you can be cool by: 77 | 78 | * **Helping each other.** Check with other students before asking a 79 | mentor for help. "Ask three, then me," is a good rule of thumb. 80 | 81 | * **Learning Python.** Today's focus is on programming, not the game 82 | of Minecraft. Remember, this is a CoderDojo, not a LAN party! 83 | 84 | 85 | Now that you know how this class works, it's time to learn how to get 86 | started with the :doc:`first steps for setup `. 87 | -------------------------------------------------------------------------------- /docs/classroom/player-controls.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Minecraft Controls 3 | ==================== 4 | 5 | This is a brief synopsis. For more details, see the `Controls article`_. 6 | 7 | .. _Controls article: http://minecraft.gamepedia.com/Controls 8 | 9 | 10 | Keyboard 11 | ======== 12 | 13 | ============ =========================================================== 14 | Keys Function 15 | ============ =========================================================== 16 | :kbd:`W` Move forward (or up, when navigating inventory) 17 | :kbd:`A` Move left 18 | :kbd:`S` Move backward (or down, when navigate inventory) 19 | :kbd:`D` Move right 20 | :kbd:`Space` Jump, double tap to start/stop flying, hold to fly higher 21 | :kbd:`Shift` Sneak, hold to fly lower 22 | :kbd:`E` Open inventory 23 | Number keys Select inventory slot item to use 24 | :kbd:`Esc` Show/hide menu 25 | :kbd:`Tab` Release mouse without showing menu 26 | :kbd:`Enter` Confirm menu selection 27 | ============ =========================================================== 28 | 29 | 30 | Mouse 31 | ===== 32 | 33 | ============ ============================================================ 34 | Movement Result 35 | ============ ============================================================ 36 | Steer Look/turn around 37 | Left button Remove block (hold) 38 | Right button Place block, hit block with sword 39 | Mouse wheel Select inventory slot item to use 40 | ============ ============================================================ 41 | -------------------------------------------------------------------------------- /docs/classroom/resources.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Resources 3 | =========== 4 | 5 | Python Programming 6 | ================== 7 | 8 | * `The Python Docs `_ cover everything you 9 | could possibly want to know about Python. 10 | 11 | * This `Python cheat sheet 12 | `_ 13 | provides a concise reference for some common Python syntax. 14 | 15 | 16 | Online Coding Classes 17 | ===================== 18 | 19 | * `Codecademy `_ 20 | 21 | * `LearnPython.org `_ 22 | 23 | * `Udacity `_ 24 | 25 | 26 | More about the Minecraft API 27 | ============================ 28 | 29 | * `The Minecraft PI Worksheet 30 | `_ 31 | provides a simple introduction to programming Minecraft with Python. 32 | 33 | * `MCPi API Basics `_ 34 | 35 | * `MCPi API Tutorial on StuffAboutCode.com `_ 36 | 37 | * The `MCPi API Reference 38 | `_ has 39 | a useful summary of all the things possible in the Python Minecraft 40 | API. 41 | 42 | * `MCPi API Examples `_ 43 | 44 | * `More MCPi scripts `_ 45 | 46 | .. note:: Although the StuffAboutCode links discuss using an Raspberry 47 | Pi, you don't need a Raspberry Pi to use the API. We're 48 | using CanaryMod server instead with the RaspberryJuice 49 | plugin. More information about that is in the 50 | :doc:`architecture guide <../reference/architecture>`. 51 | 52 | -------------------------------------------------------------------------------- /docs/classroom/setup.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | First Steps for Setup 3 | ======================= 4 | 5 | To participate in today's classroom activities, you need a few things: 6 | 7 | #. Get a PC. If you brought your own, you're set. Plug it in and get 8 | comfortable. If not, look for an unoccupied classroom PC at one of 9 | the Python-Minecraft tables. If none are available, talk to a 10 | mentor. 11 | 12 | #. Next, talk to mentor to get your :term:`lab instance connection 13 | card`. This card has the unique details you need to connect to the 14 | instance. We will need your Mojang account name (the player name, 15 | inside Minecraft) so we can set up your instance and give your 16 | player permission to connect to it. If you don't have a Mojang 17 | account, we have several available for use in the classroom. 18 | 19 | #. Make sure your PC is connected to Wi-Fi. If you are using a 20 | classroom PC, this may have already been set up. This is covered in 21 | more detail in the :doc:`Wi-Fi instructions `. 22 | 23 | #. Connect to your IPython Notebook and Minecraft worlds. If you are 24 | using a classroom PC, this may have already been set up. This is 25 | covered in more detail in the :doc:`lab instance setup instructions 26 | `. 27 | 28 | #. Test the connection between Python and Minecraft. Even if you are 29 | using a classroom PC, it is good to test out the connection 30 | yourself. Instructions are :doc:`here `. 31 | 32 | Now that you have a high-level understanding, make sure you have 33 | :doc:`Wi-Fi setup `. 34 | -------------------------------------------------------------------------------- /docs/classroom/test.rst: -------------------------------------------------------------------------------- 1 | =================== 2 | Testing the Setup 3 | =================== 4 | 5 | A very basic test will show you whether the connection is working 6 | between the Minecraft server and the IPython notebook server. 7 | 8 | #. In IPython, click on the :guilabel:`exercises` folder to navigate 9 | to where the classroom exercises are stored. 10 | 11 | #. Click on :guilabel:`Exercise 1 -- Hello World!` to open the 12 | notebook for the first exercise. Your screen should look roughly 13 | like the following: 14 | 15 | .. image:: _images/hello-world-notebook.png 16 | 17 | #. Choose :menuselection:`Cell --> Run All` from the menu. 18 | 19 | #. In the Minecraft game, look for the ``Hello Minecraft!`` 20 | message. If you don't see it, try opening chat by typing 21 | :kbd:`T`. You should see something like the following: 22 | 23 | .. image:: _images/hello-world-minecraft.png 24 | 25 | 26 | If this works, fantastic! You are ready to continue on with the 27 | :doc:`exercises `. 28 | -------------------------------------------------------------------------------- /docs/classroom/wifi.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | Connect to Wi-Fi 3 | ================== 4 | 5 | The username and password needed you need to connect to the campus 6 | Wi-Fi is printed on the name badge passed out to each student and 7 | mentor. These credentials are only good for the day of the session, so 8 | if you have credentials saved on your computer from a prior session, 9 | you will need to delete them and use the ones on your name 10 | badge. These credentials are good for a single device (e.g., one 11 | laptop). If you need an extra set of credentials for additional 12 | devices, check with one of the mentors. 13 | 14 | The official documentation for connecting to the UMN campus Wi-Fi is 15 | available in the `WiFi Setup Guides`_. You should look at the section 16 | for your specific operating system under the heading *UoM Secure*. 17 | 18 | .. _WiFi Setup Guides: http://it.umn.edu/wifi-setup-guides 19 | 20 | That said, you might be able to muddle through setting up a connection 21 | using only the key bits of information below: 22 | 23 | * Connect to the ``UofM Secure`` SSID. Other networks might seem to 24 | work (e.g., ``UofM Guest``), but they are bandwidth-restricted. You 25 | will have Internet connectivity, but will be terribly slow. 26 | 27 | * Choose ``WPA2-Enterprise`` security. 28 | 29 | * Choose ``AES`` encryption. 30 | 31 | * If you're only visiting the campus for a short time to participate 32 | in a CoderDojo event, it is probably unnecessary to configure the 33 | *Protected EAP* properties or to mess around with any advanced 34 | settings like 802.1X or its certificates. Skipping those steps means 35 | you can't be positive that your PC is talking to the 36 | University-provided Wi-Fi infrastructure, but the risk is pretty 37 | low. 38 | 39 | .. warning:: However, if you live, study, or work on campus, take 40 | the extra time to go through all the setup steps in the 41 | official documentation so you stay secure. 42 | 43 | 44 | Once Wi-Fi is working and you are able to visit websites (try the 45 | `CoderDojo site`_), move on to :doc:`connecting to your lab instance 46 | `. 47 | 48 | .. _CoderDojo site: http://www.coderdojotc.org/ 49 | -------------------------------------------------------------------------------- /docs/classroom/your-own-thing.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Doing Your Own Thing 3 | ====================== 4 | 5 | Once you've gone through the exercises and explored some of the other 6 | pre-existing scripts, here are some activities you can try when you're 7 | ready to create your own Mod: 8 | 9 | #. Imagine what you want your Mod to do. Think through the behaviors a 10 | player will see. Think about what they can't see. Try to write it 11 | down. 12 | 13 | #. Next, see if you can explain it to another person. Was anything 14 | unclear? Did they see any problems that you need to fix? 15 | 16 | #. Talk to a mentor or another student about how they might tackle 17 | this challenge in Python. 18 | 19 | #. Look through existing code for something that seems similar. It's 20 | often easier to start from something that already exists, making 21 | the changes you need, than starting from scratch. 22 | 23 | #. If you do have to start from scratch, try writing little bits at a 24 | time and testing them out. That way, you can tell if you are on the 25 | right track or not. 26 | 27 | Finally, show it off. If you create something cool, please 28 | share. Maybe it will be an example for future students to study some 29 | day! 30 | -------------------------------------------------------------------------------- /docs/contents.rst: -------------------------------------------------------------------------------- 1 | ============================================================== 2 | Build Worlds in Minecraft with Python Documentation Contents 3 | ============================================================== 4 | 5 | This is the master table of contents. However, you will probably find 6 | the :doc:`Overview Page ` to be more user-friendly. 7 | 8 | .. toctree:: 9 | :hidden: 10 | 11 | index 12 | 13 | .. toctree:: 14 | :maxdepth: 2 15 | 16 | classroom/index 17 | other-setups/index 18 | mentors/index 19 | reference/index 20 | faq/index 21 | glossary 22 | todo 23 | release-notes 24 | 25 | 26 | Indices and Tables 27 | ================== 28 | 29 | * :ref:`genindex` 30 | * :ref:`search` 31 | -------------------------------------------------------------------------------- /docs/faq/index.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Python Minecraft FAQ 3 | ====================== 4 | 5 | Why can't I... 6 | ============== 7 | 8 | ... change anything in my world? 9 | 10 | If you can't create or destroy blocks in your world through the 11 | Minecraft game itself, you probably need to make sure that your 12 | player has Operator_ status on the game server. 13 | 14 | .. _Operator: http://minecraft.gamepedia.com/Operator 15 | 16 | 17 | How do I... 18 | =========== 19 | 20 | ... create a new world? 21 | 22 | To create a new world, you need to use the :command:`/createworld 23 | WORLDNAME` to create a world named *WORLDNAME*. Then use the 24 | command :command:`/spawn WORLDNAME` to switch to that world. To 25 | create and joing a world named ``Mine``, you would use the 26 | following two commands:: 27 | 28 | /createworld Mine 29 | /spawn Mine 30 | 31 | The world you are in when the game starts it called ``default``. To 32 | return to it, you would use the command :command:`/spawn default`. 33 | 34 | 35 | Why is... 36 | ========= 37 | 38 | ... my network connection so slow? 39 | 40 | You might have connected via Wi-Fi to ``UofM Guest`` instead of 41 | ``UofM Secure``. The ``Guest`` network has much less bandwidth, and 42 | is too slow for most useful work. 43 | -------------------------------------------------------------------------------- /docs/glossary.rst: -------------------------------------------------------------------------------- 1 | ========== 2 | Glossary 3 | ========== 4 | 5 | .. If you add new terms, please preserve the alphabetical ordering. 6 | 7 | .. glossary:: 8 | 9 | code group 10 | Code groups are topics in the Twin Cities' CoderDojo. When 11 | students sign up to attend, they indicate interest in three 12 | different code groups. They get assigned to a specific code 13 | group once the number of mentors is known. This usually happens 14 | a couple of days before the event. 15 | 16 | command line 17 | The command line is the place where you type commands and your 18 | computer executes them. On Windows, you need to launch the 19 | :command:`Command Prompt`. On Ubuntu Linux and on OS X, you can 20 | launch a program called :command:`Terminal`. 21 | 22 | lab instance 23 | In the hosted environment we use for the CoderDojo classes, each 24 | student has a private instance that contains a Minecraft server 25 | and world, an IPython notebook server, and copies of Python 26 | scripts with exercises and example programs. 27 | 28 | lab instance connection card 29 | A piece of paper that has the address of your private Minecraft 30 | server, the address of your private IPython notebook server, and 31 | the password needed to connect to it. 32 | 33 | text editor 34 | A text editor is a program that is lets a user edit plain text 35 | files. Most programs are stored in plain text files, so computer 36 | programmers often use text editors to create and change these 37 | files. 38 | 39 | On a Windows PC, the text editor that comes with the Windows 40 | itself is called :command:`Notepad`. On a many versions of 41 | Linux, a program named :command:`gedit` is often installed. On 42 | Mac OS X, the text editor is commonly called 43 | :command:`TextEdit`. 44 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | ======================================= 2 | Build Worlds in Minecraft with Python 3 | ======================================= 4 | 5 | This documentation supports the `CoderDojo Twin Cities'`_ *Build 6 | worlds in Minecraft with Python* code group. This group intends to 7 | teach you how to use Python_, a general purpose programming language, 8 | to mod the popular game called Minecraft_. It is targeted at students 9 | aged 10 to 17 who have some programming experience in another 10 | language. For example, in Scratch_. 11 | 12 | .. _CoderDojo Twin Cities': http://www.coderdojotc.org/ 13 | .. _Python: https://www.python.org 14 | .. _Minecraft: https://minecraft.net/ 15 | .. _Scratch: http://scratch.mit.edu/ 16 | 17 | 18 | In the Classroom? 19 | ================= 20 | 21 | Are you in the classroom right now? This section is for you! Visit the 22 | first page linked below (hint: it reads *Overview*), read through the 23 | material, and then click through the link under the :guilabel:`Next 24 | topic` heading on each page to work through all the documentation. 25 | 26 | * **Today's class:** 27 | :doc:`Overview ` 28 | 29 | * **Setup:** 30 | :doc:`First steps ` | 31 | :doc:`Connect to Wi-Fi ` | 32 | :doc:`Connect to your lab instance ` | 33 | :doc:`Test the setup ` 34 | 35 | * **Getting to work:** 36 | :doc:`Prepared exercises ` | 37 | :doc:`Other scripts to explore ` | 38 | :doc:`Doing your own thing ` 39 | 40 | * **Reference material:** 41 | :doc:`Controlling Minecraft from Python ` | 42 | :doc:`Minecraft controls ` | 43 | :doc:`Other resources ` 44 | 45 | * **Architecture Overview:** The :doc:`architecture overview 46 | ` explains the major components of the 47 | environment we use for our exercises. 48 | 49 | 50 | Getting Help 51 | ============ 52 | 53 | Having trouble? Here are some pointers this might be useful: 54 | 55 | * If you are reading an off-line version of our documentation, you 56 | might want to refer to the `authoritative site`_. This site will 57 | always have the latest and greatest material. 58 | 59 | * Take a look at the :doc:`FAQ `. We are loading this up 60 | with answers to common questions. Maybe the answer to your question 61 | is already here. 62 | 63 | * Looking for specific information? You might find it in the 64 | :doc:`detailed table of contents `, or you might be able 65 | to use the :ref:`search` or :ref:`genindex` to help you locate it. 66 | 67 | * Our :doc:`glossary ` might define a term that is new to 68 | you. 69 | 70 | * If something seems different than the way it was before, consult the 71 | :doc:`release notes ` for more detail. 72 | 73 | * If something is still unclear, we really would like to know. Please 74 | visit our `ticket tracker`_ to let us know about the problem. Use 75 | the :guilabel:`New Issue` button. 76 | 77 | .. _authoritative site: http://coderdojotc.readthedocs.org/projects/python-minecraft/en/latest/ 78 | .. _ticket tracker: https://github.com/CoderDojoTC/python-minecraft/issues 79 | 80 | 81 | Other Setups 82 | ============ 83 | 84 | Here are some instructions for setting up software to support 85 | different circumstances: 86 | 87 | * **At Home, The Easy Way:** If you are interested in recreating the 88 | environment we use in the CoderDojo lab, but for a single user, on 89 | your own PC, you should consult our guide for :doc:`Vagrant 90 | `. 91 | 92 | * **At Home, The Hard Way:** If you are interested in installing all 93 | the software needed to run these examples directly on your PC 94 | (without using Vagrant to simplify the job), we currently have a 95 | guide that covers doing so on :doc:`Windows `. Users 96 | of other platforms can consult this guide and try to adapt it for 97 | their circumstances. Ultimately, we intend to also provide guides 98 | for :doc:`Apple's OS X ` and :doc:`Ubuntu Linux 99 | `. 100 | 101 | 102 | Mentors 103 | ======= 104 | 105 | Mentors need docs too! Here they are: 106 | 107 | * **Core Mentor Guide:** 108 | :doc:`Being a CoderDojo mentor ` | 109 | :doc:`Being a Python Minecraft mentor ` 110 | 111 | * **Python Minecraft Project Technology:** 112 | :doc:`Project technology ` | 113 | :doc:`Project maintenance ` | 114 | :doc:`Running a lab server ` 115 | 116 | 117 | Copyright 118 | ========= 119 | 120 | This document and the supporting code has been created by multiple 121 | contributors_. 122 | 123 | .. _contributors: https://github.com/CoderDojoTC/python-minecraft/graphs/contributors 124 | -------------------------------------------------------------------------------- /docs/mentors/general.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | Being a CoderDojo Mentor 3 | ========================== 4 | 5 | What is a Mentor? 6 | ================= 7 | 8 | Being a CoderDojo Mentor is like being a guide on an adventure. It 9 | helps if you know where you're going, but more important is a sense of 10 | curiosity and a willingness to work alongside the students as they 11 | learn. We haven't had a chance yet to find write this guide about 12 | being a mentor at the CoderDojo Twin Cities, but there are lots of 13 | other resources available: 14 | 15 | * `CoderDojo Twin Cities' FAQ on Mentoring`_, retrieved on February 8, 2015. 16 | * `CoderDojo's Mentor Guide`_, retrieved on February 8, 2015. 17 | * `CoderDojo Brisbane's Mentors Guide`_, retrieved on February 8, 2015. 18 | * `CoderDojo Brighton's Info for Mentors`_, retrieved on February 8, 2015. 19 | 20 | .. _CoderDojo Twin Cities' FAQ on Mentoring: http://www.coderdojotc.org/faq/#mentoring 21 | .. _CoderDojo's Mentor Guide: https://speakerdeck.com/helloworldfoundation/coderdojo-mentor-guide 22 | .. _CoderDojo Brisbane's Mentors Guide: http://bit.ly/CoderDojoBne_Mentor_Guide 23 | .. _CoderDojo Brighton's Info for Mentors: http://coderdojobrighton.co.uk/mentors/ 24 | 25 | 26 | CoderDojo Twin Cities High-level Overview 27 | ========================================= 28 | 29 | Events are usually held once or twice a month. Events are held on the 30 | Saturdays on the University of Minnesota campus. 31 | 32 | Students are in the classroom for about two hours, typically between 33 | 1:30pm and 3:30pm. Mentors are asked to arrive around 12:45pm to help 34 | with setup, and to stay a bit after to help with cleanup. 35 | 36 | Classroom setup includes: 37 | 38 | #. Selecting the right number of tables for the expected number of 39 | students in each :term:`code group`. Each table in our usual 40 | classroom holds about nine students comfortably. 41 | 42 | #. Retrieving the mentor and student name badges for the :term:`code 43 | group`, and stuffing them in the badge holders. 44 | 45 | #. For students using classroom laptops, placing the laptops on the 46 | desks, connecting them to power supplies, logging them into the 47 | campus Wi-Fi, and preparing any needed software. 48 | 49 | Students may either bring their own laptop, or use one of the 50 | classroom laptops. Classroom laptops are all Apple Macs of varying 51 | vintages. Students arrive with a variety of different kinds of 52 | computers. Most are running some version of Microsoft Windows. 53 | -------------------------------------------------------------------------------- /docs/mentors/index.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Mentor Documentation 3 | ====================== 4 | 5 | The section contains documentation useful for mentors supporting the 6 | *Build worlds in Minecraft with Python* code group. 7 | 8 | First, please familiarize yourself with the :doc:`documentation used 9 | by the students during a class <../classroom/index>`, then return to 10 | this document. We're going to try to avoid repeating ourselves. 11 | 12 | Next, review the core overview for mentors: 13 | 14 | .. toctree:: 15 | :maxdepth: 1 16 | 17 | general 18 | python-minecraft 19 | lessons-learned 20 | 21 | After reviewing the material above, you are probably well ready to be 22 | a mentor at a Dojo event. We look forward to seeing you there! 23 | 24 | If you are hosting the technology used for a session, you should 25 | consult these guides: 26 | 27 | .. toctree:: 28 | :maxdepth: 1 29 | 30 | lab-server 31 | 32 | The following documentation covers various kinds of project 33 | technology, maintenance, and other tasks: 34 | 35 | .. toctree:: 36 | :maxdepth: 1 37 | 38 | project-technology 39 | maintenance 40 | -------------------------------------------------------------------------------- /docs/mentors/lessons-learned.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Lessons Learned 3 | ================= 4 | 5 | We are attempting to capture lessons learned in the course of 6 | conducting the classroom sessions over time. 7 | 8 | 9 | Lessons/Thoughts from 2015-01-24 10 | ================================ 11 | 12 | The WiFi setup on name-badges was much easier to manage than trying to 13 | cross credentials off lists. It did take a little more coordination to 14 | get WiFi set up on Dojo-provided PCs. We had to line up the badges on 15 | the appropriate PCs, and then log them in. 16 | 17 | We had a lot of students who came without a PC, or without a PC that 18 | could run Minecraft (e.g., one student brought a Chromebook). This put 19 | us behind the curve because several students didn't have a PC to work 20 | from. We eventually settled on having them join another student with a 21 | working PC, but it was suboptimal. 22 | 23 | There are a variety of problems running Minecraft on the PCs: 24 | 25 | * We had some student experience crashes upon trying to connect their 26 | PC to the server. They could join servers with 1.8, but on 1.7.10, 27 | they got a java OutOfBounds exception crash. 28 | -------------------------------------------------------------------------------- /docs/mentors/maintenance.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | Project Maintenance 3 | ===================== 4 | 5 | Notes on various maintenance tasks. 6 | 7 | .. todo:: This document needs to be drafted. 8 | 9 | 10 | Creating/updating documentation 11 | =============================== 12 | 13 | 14 | Creating/updating examples 15 | ========================== 16 | 17 | 18 | Updating the Student Environment 19 | ================================ 20 | 21 | 22 | Building a Lab Server on a Host 23 | =============================== 24 | -------------------------------------------------------------------------------- /docs/mentors/project-technology.rst: -------------------------------------------------------------------------------- 1 | ==================== 2 | Project Technology 3 | ==================== 4 | 5 | In the very barest of sketches, this document lays out the different 6 | technologies and resources used for the Python Minecraft :term:`code 7 | group`. 8 | 9 | 10 | Technologies 11 | ============ 12 | 13 | Jupyter 14 | ------- 15 | 16 | The interface to Python used by the students during our workshop is 17 | the `Jupyter Notebook`_. The Python code is embedded in Jupyter 18 | Notebook files, which are the files named :file:`*.ipynb` in the 19 | source code repository. 20 | 21 | The Jupyter project hosts an `online notebook viewer`_ that can turn 22 | these ``ipynb`` files into easily readable versions. Just paste any 23 | URL from a GitHub file into the box on the NBViewer site, and and you will 24 | it will generate a linkable `result like this one`_. 25 | 26 | .. _Jupyter Notebook: https://jupyter-notebook.readthedocs.org/en/latest/ 27 | .. _online notebook viewer: http://nbviewer.jupyter.org 28 | .. _result like this one: http://nbviewer.jupyter.org/github/CoderDojoTC/python-minecraft/blob/master/classroom-code/exercises/ 29 | 30 | 31 | Online Resources 32 | ================ 33 | 34 | Source Code Repository 35 | ---------------------- 36 | 37 | Our `code repository`_ lives on GitHub. This repository is the master 38 | source for the documents, code examples, and scripts and tools used to 39 | support the class. 40 | 41 | We try to follow the *feature branch workflow* in our Git 42 | repository. Atlassian provides a `nice overview`_ of this workflow. 43 | 44 | .. _code repository: https://github.com/CoderDojoTC/python-minecraft 45 | .. _nice overview: https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow 46 | 47 | 48 | Mailing Lists 49 | ------------- 50 | 51 | Our `mailing list`_ is hosted on Google Groups. It is a public group, 52 | open to all. 53 | 54 | .. _mailing list: https://groups.google.com/a/coderdojotc.org/forum/?hl=en#!forum/group-python 55 | 56 | 57 | Project Documentation 58 | --------------------- 59 | 60 | The source code for our documentation is in the `code repository`_. A 61 | readable, online version is available in our project's `Read the Docs 62 | site`_. Any changes to tracked branches in the repository (especially 63 | ``master``) will result in the project documentation being rebuilt so 64 | they are current. The Read the Docs `project page`_ is the 65 | administrative interface for this online version. 66 | 67 | .. _Read the Docs site: http://coderdojotc.readthedocs.org/projects/python-minecraft/en/latest/ 68 | .. _project page: https://readthedocs.org/projects/python-minecraft/ 69 | 70 | 71 | Docker Hub 72 | ---------- 73 | 74 | We use Docker Hub to host a public repository that contains the 75 | `student image`_ used on the lab server for each student. These images 76 | are built using the :file:`Dockerfile` contained in 77 | :file:`lab-server/student-env-image` of our source code 78 | repository. Once built, they are pushed to the Docker Hub so they can 79 | be retrieved by anyone hosting a lab server, or by students using 80 | Vagrant to host an environment on their personal computer. 81 | 82 | .. _student image: https://registry.hub.docker.com/u/coderdojotc/python-minecraft-student/ 83 | -------------------------------------------------------------------------------- /docs/mentors/python-minecraft.rst: -------------------------------------------------------------------------------- 1 | ================================= 2 | Being a Python Minecraft Mentor 3 | ================================= 4 | 5 | The marketing material for the Python Minecraft code group describes 6 | it as follows: 7 | 8 | Use Python, a general purpose programming language, to mod the 9 | popular Minecraft game. Best for coders 10+ or younger with some 10 | experience in programming (like Scratch!) 11 | 12 | It recommends that students be between the ages of 10 and 17, with 13 | some experience in programming. 14 | 15 | Mentors in this :term:`code group` ideally have some of the following 16 | experience, though none of these are a hard requirement: 17 | 18 | * Python programming. 19 | 20 | * IPython usage. 21 | 22 | * Minecraft usage. 23 | 24 | * Teaching skills. 25 | -------------------------------------------------------------------------------- /docs/other-setups/index.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Other Setups 3 | ============== 4 | 5 | When you are participating in a CoderDojo class, we host a lab server 6 | so that most of the setup is already done for you. However, if you 7 | want to do these exercises on your home PC, you will need to choose 8 | one of the approaches described below. 9 | 10 | Setting up environments like this can be tricky. The simplest way is 11 | to use a tool called Vagrant, and described in the chapter below. 12 | 13 | .. toctree:: 14 | :maxdepth: 1 15 | 16 | vagrant 17 | 18 | If you don't use Vagrant, you need to perform many, many more 19 | steps. These steps depend on the operating system you are using. The 20 | chapters below give you some instructions for these steps: 21 | 22 | .. toctree:: 23 | :maxdepth: 1 24 | 25 | windows 26 | osx 27 | ubuntu 28 | -------------------------------------------------------------------------------- /docs/other-setups/osx.rst: -------------------------------------------------------------------------------- 1 | ======================== 2 | Setup for Apple's OS X 3 | ======================== 4 | 5 | .. todo:: If you are able to help write (or help write) this chapter 6 | of the documentation, please take ownership of the GitHub 7 | issue: 8 | https://github.com/CoderDojoTC/python-minecraft/issues/3 9 | -------------------------------------------------------------------------------- /docs/other-setups/ubuntu.rst: -------------------------------------------------------------------------------- 1 | .. _setup-ubuntu: 2 | 3 | ======================== 4 | Setup for Ubuntu Linux 5 | ======================== 6 | 7 | .. todo:: More to come. 8 | -------------------------------------------------------------------------------- /docs/reference/architecture.rst: -------------------------------------------------------------------------------- 1 | ============================== 2 | Overview of the Architecture 3 | ============================== 4 | 5 | There are many different programs and tools involved in these 6 | activities. This document introduces you to these pieces. 7 | 8 | * `Minecraft`_ 9 | * `CanaryMod Server`_ 10 | * `RaspberryJuice for CanaryMod`_ 11 | * `Git`_ 12 | * `Python`_ 13 | * `A Text Editor`_ 14 | 15 | 16 | Minecraft 17 | ========= 18 | 19 | This is what you run when you start the game itself. Most of the time, 20 | it is actually the `Minecraft launcher`_, which you have downloaded_ 21 | from Mojang. This is sometimes referred to as the *client*, because in 22 | these activities, we will connect it to a separate server that you 23 | will control through Python. 24 | 25 | .. _Minecraft launcher: http://minecraft.gamepedia.com/Minecraft_launcher 26 | .. _downloaded: https://minecraft.net/download 27 | 28 | 29 | CanaryMod Server 30 | ================ 31 | 32 | CanaryMod_ is a Minecraft server_. Like the vanilla Minecraft server 33 | from Mojang itself, it can be used to host a multiplayer_ game of 34 | Minecraft. Unlike the vanilla server, CanaryMod has a plugin API which 35 | allows it to be customized by developers. Unlike the CraftBukkit 36 | server, it is still available to download in both source code and 37 | compiled forms (as of October 2014). 38 | 39 | .. _CanaryMod: http://canarymod.net/ 40 | .. _server: http://minecraft.gamepedia.com/Server 41 | .. _multiplayer: http://minecraft.gamepedia.com/Multiplayer 42 | 43 | 44 | RaspberryJuice for CanaryMod 45 | ============================ 46 | 47 | Mojang release a special version of Minecraft (called the `Minecraft: 48 | Pi Edition`_) that runs on a small, inexpensive computer called the 49 | Raspberry Pi. This version of Minecraft is special because it is 50 | available to download and use for no cost, and because it comes with 51 | support for modifying the game server's behavior in multiple 52 | programming languages. The only downside to this special version is 53 | that it **requires** a Raspberry Pi, and cannot be run on a regular 54 | computer. While a Raspberry Pi is relatively inexpensive, most 55 | students probably already have access to a regular computer than can 56 | run the normal version of Minecraft, so we've looked for an 57 | alternative. 58 | 59 | The original alternative came from the RaspberryJuice_ plugin for the 60 | CraftBukkit server. This plugin supports the same methods for 61 | customizing the server's behavior as the Minecraft: Pi Edition, but it 62 | can be used with the PC version of Minecraft. 63 | 64 | Due to some turmoil in the Bukkit project beginning around early 65 | September 2014, CraftBukkit is unavailable for the time being. The 66 | good news is that the CanaryMod server also has a `plugin equivalent 67 | to RaspberryJuice`_, so it is the one we can use. 68 | 69 | .. _`Minecraft: Pi Edition`: http://pi.minecraft.net/ 70 | .. _RaspberryJuice: http://dev.bukkit.org/bukkit-plugins/raspberryjuice/ 71 | .. _`plugin equivalent to RaspberryJuice`: http://canarymod.net/forum/viewtopic.php?f=33&t=3812 72 | 73 | 74 | Git 75 | === 76 | 77 | Git is a `developer's tool`_ for keeping track of changes made to 78 | files. These kinds of tools are commonly referred to as Version 79 | Control Systems (VCS) or Source Code Management systems (SCM), because 80 | developers use them to keep track of the files that go into the 81 | programs they write. The examples used in the CoderDojo class are kept 82 | in a Git repository, along with the files that make up the 83 | RaspberryJuice plugin. 84 | 85 | .. _`developer's tool`: http://git-scm.com/ 86 | 87 | 88 | Python 89 | ====== 90 | 91 | Python is the language in which we will develop our mods for 92 | Minecraft. It is free and open source, it runs on pretty much any 93 | computer around. It is both easy for beginners and powerful enough for 94 | very complicated or sophisticated programs. 95 | 96 | 97 | A Text Editor 98 | ============= 99 | 100 | Python programs are written in plain text files. As such, you will 101 | need a program that helps create and update these files. There are 102 | many available, and most computers even come with one out of the 103 | box. However, some editors have features that make it easier to read, 104 | write, and test computer programs, so we will select one of those. 105 | -------------------------------------------------------------------------------- /docs/reference/index.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Reference 3 | =========== 4 | 5 | This section contains reference material and covers other random 6 | topics. 7 | 8 | .. toctree:: 9 | :maxdepth: 1 10 | :glob: 11 | 12 | * 13 | -------------------------------------------------------------------------------- /docs/todo.rst: -------------------------------------------------------------------------------- 1 | ============================ 2 | Documentation Needing Work 3 | ============================ 4 | 5 | The following is an auto-generated list of documentation files with a 6 | "to do" note in them (``.. todo:: Your note goes here...``). If you 7 | are looking for something to do, this could give you some ideas. 8 | 9 | .. todolist:: 10 | -------------------------------------------------------------------------------- /fabfile.py: -------------------------------------------------------------------------------- 1 | """This is a `Fabric`_ script that helps automate tasks performed while 2 | developing and delivering the course. 3 | 4 | .. _Fabric: http://www.fabfile.org/ 5 | 6 | Invoke it with the :command:`fab` command. 7 | """ 8 | 9 | import os 10 | import os.path 11 | 12 | # TODO: Look at using docker-fabric in place of directly using 13 | # docker-py. It seems like it would help manage remote docker 14 | # instances through the Fabric SSH tunnels instead of needing to set 15 | # up a CA, create client and server certs, etc. 16 | from docker import Client 17 | 18 | from fabric.api import * 19 | from fabric.colors import red 20 | 21 | 22 | # TODO: Create some tasks that enable the user to manage the classroom 23 | # environment on AWS using boto. 24 | 25 | 26 | def topdir(): 27 | """Returns the directory where the fabfile is located""" 28 | return os.path.dirname(env.real_fabfile) 29 | 30 | 31 | @task 32 | def virtualenv_install(): 33 | """Install/upgrade the virtual environment""" 34 | if None == os.environ.get('VIRTUAL_ENV'): 35 | abort(red("VIRTUAL_ENV variable missing from environment. Are you in an active virtualenv?")) 36 | with lcd(topdir()): 37 | local("pip install --upgrade -r requirements.txt") 38 | 39 | 40 | @task 41 | def docs_build(): 42 | """Build a local copy of the documentation""" 43 | with lcd(os.path.join(topdir(), 'docs')): 44 | local("make html") 45 | 46 | 47 | @task 48 | def docs_show(): 49 | """Show the local copy of the documentation in a browser""" 50 | # Make sure the docs are built 51 | docs_build() 52 | 53 | # Launch a browser. 54 | # TODO: Add some code to do the right thing on operating systems other than Ubuntu/Debian 55 | with lcd(topdir()): 56 | local("sensible-browser docs/_build/html/index.html") 57 | 58 | 59 | def student_env_container(base_url=None): 60 | """Return the docker.container of the first Docker instance that is 61 | hosting the python-minecraft student environment. Returns None if 62 | none are found. 63 | 64 | """ 65 | 66 | cli = Client(base_url) 67 | for container in cli.containers(): 68 | if container['Image'].startswith(u'coderdojotc/python-minecraft-student'): 69 | return container 70 | 71 | return None 72 | 73 | 74 | @task 75 | def env_sync(): 76 | """Synchronize local source files with those in the environment 77 | 78 | This will copy files into and out of the environment.""" 79 | 80 | print(red("Use the Unison keyboard interface to specify which files to sync")) 81 | container = student_env_container() 82 | with lcd(topdir()): 83 | local("docker exec -it {Id} sync-notebooks.sh".format(**container)) 84 | # TODO: Would be nice to figure out why this returns an exit code 85 | # of 1, prompting warnings from local(). 86 | 87 | 88 | @task 89 | def env_up(): 90 | """Start up the environment""" 91 | with lcd(topdir()): 92 | local("vagrant up --provider=docker") 93 | 94 | 95 | @task 96 | def env_down(): 97 | """Stop the environment""" 98 | with lcd(topdir()): 99 | local("vagrant halt") 100 | 101 | 102 | @task 103 | def env_destroy(): 104 | """Destroy the environment""" 105 | with lcd(topdir()): 106 | local("vagrant destroy") 107 | -------------------------------------------------------------------------------- /lab-server/README.rst: -------------------------------------------------------------------------------- 1 | ================ 2 | The Lab Server 3 | ================ 4 | 5 | Please consult the documentation available in 6 | :file:`docs/reference/lab-server.rst`. 7 | -------------------------------------------------------------------------------- /lab-server/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # This Vagrantfile sets up a Vagrant box that provides the full 5 | # python-minecraft lab server environment. This lab server environment 6 | # uses Docker to create a private environment for each student. Each 7 | # environment consists of a CanaryMod server, configured with the 8 | # RaspberryJuice plugin, and set up to host a Minecraft world. It also 9 | # includes an IPython Notebook server, configured to allow students to 10 | # work through the exercises of the python-minecraft code group. 11 | 12 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 13 | VAGRANTFILE_API_VERSION = "2" 14 | 15 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 16 | # All Vagrant configuration is done here. The most common configuration 17 | # options are documented and commented below. For a complete reference, 18 | # please see the online documentation at vagrantup.com. 19 | 20 | # Every Vagrant virtual environment requires a box to build off of. 21 | config.vm.box = "ubuntu/trusty64" 22 | 23 | # Forward a range of ports from the host to guest. 24 | for i in 48000..48999 25 | config.vm.network :forwarded_port, guest: i, host: i 26 | end 27 | 28 | # Provider-specific configuration so you can fine-tune various 29 | # backing providers for Vagrant. These expose provider-specific options. 30 | # Example for VirtualBox: 31 | # 32 | config.vm.provider "virtualbox" do |vb| 33 | # Set vb.gui to true to leave a console running for the box. Leave 34 | # it unset, or set to false, to get a headless box. 35 | # vb.gui = true 36 | 37 | # Use VBoxManage to change the memory allocated to the box: 38 | vb.customize ["modifyvm", :id, "--memory", "2048"] 39 | end 40 | 41 | # Run the configuration script on the Vagrant box to finish setting 42 | # it up. 43 | config.vm.provision "shell", path: "lab-server-setup.sh" 44 | end 45 | -------------------------------------------------------------------------------- /lab-server/canary-build-image/Dockerfile: -------------------------------------------------------------------------------- 1 | # Builds a Docker image that is suitable for compiling Canary. This is 2 | # helpful when/if we need to make a local build of Canary. 3 | 4 | FROM ubuntu:14.04 5 | MAINTAINER Mike McCallister 6 | 7 | # Pull in the components we need from Ubuntu. This is done here 8 | # instead of in the server setup script because it lets Docker take 9 | # advantage of its cache, which greatly speeds up subsequent builds. 10 | 11 | RUN apt-get update \ 12 | && apt-get install -y \ 13 | git-core \ 14 | maven \ 15 | openjdk-7-jdk \ 16 | && apt-get clean 17 | 18 | # This is intended to be an interactive environment in which you can 19 | # build Canary. 20 | CMD ["bash", "-l"] 21 | -------------------------------------------------------------------------------- /lab-server/canary-build-image/README.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | To Build Canary 3 | ================= 4 | 5 | Create a Docker Data Volume Container to hold our local copy of the 6 | Canary code and built objects:: 7 | 8 | mkdir /tmp/canary-build-dir # Or something more permanent 9 | sudo docker run -d -v /tmp/canary-build-dir:/canary-build-dir --name canary-build-data ubuntu:14.04 echo Data-only container for building Canary 10 | 11 | Build our Docker image:: 12 | 13 | sudo docker build -t "canary-builder" . 14 | 15 | Launch a container based on the builder image:: 16 | 17 | sudo docker run -it --volumes-from canary-build-data canary-builder 18 | 19 | Once at the bash prompt inside the container, change to 20 | ``/canary-build-dir``, clone the source repos, build, etc. 21 | 22 | cd /canary-build-dir 23 | git clone https://github.com/CanaryModTeam/CanaryLib.git 24 | git clone https://github.com/CanaryModTeam/CanaryMod.git 25 | cd CanaryLib 26 | mvn package install 27 | cd ../CanaryMod 28 | mvn package 29 | 30 | .. note:: You can also edit the code in source of the volume 31 | (:file:`/tmp/canary-build-dir`, in the example above), and 32 | just use the Docker container for building. 33 | 34 | The resulting binary should be in CanaryMod/target. 35 | -------------------------------------------------------------------------------- /lab-server/controller/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the config file, since it probably contains sensitive data 2 | lsc.ini 3 | -------------------------------------------------------------------------------- /lab-server/controller/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Mike McCallister 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lab-server/controller/README.rst: -------------------------------------------------------------------------------- 1 | ======================= 2 | Lab Server Controller 3 | ======================= 4 | 5 | Please consult the documentation available in 6 | :file:`docs/reference/lab-server.rst`. 7 | -------------------------------------------------------------------------------- /lab-server/controller/cliffuni/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/lab-server/controller/cliffuni/__init__.py -------------------------------------------------------------------------------- /lab-server/controller/cliffuni/formatters.py: -------------------------------------------------------------------------------- 1 | """Output formatters that support unicode. 2 | """ 3 | 4 | import csv 5 | 6 | from cliff.formatters.base import ListFormatter, SingleFormatter 7 | import csvkit.unicsv 8 | 9 | 10 | class UniCsvFormatter(ListFormatter): 11 | """Unicode CSV file""" 12 | 13 | 14 | QUOTE_MODES = { 15 | 'all': csv.QUOTE_ALL, 16 | 'minimal': csv.QUOTE_MINIMAL, 17 | 'nonnumeric': csv.QUOTE_NONNUMERIC, 18 | 'none': csv.QUOTE_NONE, 19 | } 20 | 21 | def add_argument_group(self, parser): 22 | group = parser.add_argument_group('Unicode CSV Formatter') 23 | group.add_argument( 24 | '--uquote', 25 | choices=sorted(self.QUOTE_MODES.keys()), 26 | dest='quote_mode', 27 | default='nonnumeric', 28 | help='when to include quotes, defaults to nonnumeric', 29 | ) 30 | 31 | def emit_list(self, column_names, data, stdout, parsed_args): 32 | writer = csvkit.unicsv.UnicodeCSVWriter(stdout, 33 | quoting=self.QUOTE_MODES[parsed_args.quote_mode], 34 | ) 35 | writer.writerow(column_names) 36 | for row in data: 37 | writer.writerow(row) 38 | return 39 | -------------------------------------------------------------------------------- /lab-server/controller/lsc/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ['__version__'] 2 | 3 | version_info = '1.2.0' 4 | try: 5 | __version__ = '1.2.0' 6 | except AttributeError: 7 | __version__ = None 8 | -------------------------------------------------------------------------------- /lab-server/controller/lsc/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/lab-server/controller/lsc/commands/__init__.py -------------------------------------------------------------------------------- /lab-server/controller/lsc/commands/environment.py: -------------------------------------------------------------------------------- 1 | ''' Command line handlers that help produce the actual directory files 2 | ''' 3 | 4 | import logging 5 | import os 6 | 7 | from cliff.lister import Lister 8 | 9 | 10 | class Test(Lister): 11 | """Checks the environment. 12 | 13 | It confirms that the config file is present. It validates that the 14 | information in the config file allows it to reach the Control 15 | Sheet used to manage the student instances. 16 | """ 17 | 18 | log = logging.getLogger(__name__) 19 | 20 | def take_action(self, parsed_args): 21 | return (('Name', 'Size'), 22 | ((n, os.stat(n).st_size) for n in os.listdir('.')) 23 | ) 24 | -------------------------------------------------------------------------------- /lab-server/controller/lsc/commands/lab.py: -------------------------------------------------------------------------------- 1 | '''Command line handlers for managing the Lab.''' 2 | 3 | from itertools import chain 4 | 5 | import logging 6 | import os 7 | 8 | from cliff.command import Command 9 | from cliff.lister import Lister 10 | 11 | import lsc.config as config 12 | import lsc.model.controlsheet as controlsheet 13 | import lsc.model.instance as instance 14 | 15 | 16 | class Show(Lister): 17 | '''Show the current state of the lab, from the Control Sheet 18 | ''' 19 | 20 | log = logging.getLogger(__name__) 21 | 22 | def take_action(self, parsed_args): 23 | '''Method invoked by the Cliff framework''' 24 | 25 | # Obtain the data from the Google Sheet 26 | cs = controlsheet.Data(email=config.email, 27 | password=config.password, 28 | sheetname=config.spreadsheet, 29 | tabname=config.worksheet) 30 | 31 | return (cs.headers, 32 | # Get only the column tuples from each Record 33 | [rec.cols for rec in cs.records()]) 34 | 35 | 36 | class ProcessCommands(Lister): 37 | '''Walks through the Control Sheet and attempts to act on each command 38 | 39 | It also checks the current state of each instance and updates the 40 | appropriate columns in the Control Sheet. 41 | 42 | ''' 43 | 44 | log = logging.getLogger(__name__) 45 | 46 | def take_action(self, parsed_args): 47 | '''Method invoked by the Cliff framework''' 48 | 49 | # Obtain the data from the Google Sheet 50 | cs = controlsheet.Data(email=config.email, 51 | password=config.password, 52 | sheetname=config.spreadsheet, 53 | tabname=config.worksheet) 54 | 55 | # Work through each record in the control sheet 56 | ret_val = [] 57 | for rec in cs.records(): 58 | # Update the record with state we can determine 59 | inst = instance.Instance(rec) 60 | inst.gather_status() 61 | 62 | # Process the commands we know 63 | inst.dispatch() 64 | 65 | # Write the record if needed 66 | cs.update(rec) 67 | 68 | # Save it, temp, so we can list it 69 | ret_val.append(rec.cols) 70 | 71 | return (cs.headers, ret_val) 72 | -------------------------------------------------------------------------------- /lab-server/controller/lsc/config.py: -------------------------------------------------------------------------------- 1 | '''Config object for the lsc project''' 2 | 3 | import ConfigParser 4 | import os.path 5 | 6 | CONFIG_FILENAME = 'lsc.ini' 7 | CONFIG_SEARCH_PATH = ['.'] 8 | 9 | # Try and read in the configuration file and set the necessary 10 | # variables 11 | 12 | _config = ConfigParser.SafeConfigParser() 13 | 14 | _config.read([os.path.join(dirname, CONFIG_FILENAME) 15 | for dirname in CONFIG_SEARCH_PATH]) 16 | 17 | # These are the values we expect to find 18 | email = _config.get('Lab Config Sheet', 'email') 19 | password = _config.get('Lab Config Sheet', 'password') 20 | spreadsheet = _config.get('Lab Config Sheet', 'spreadsheet') 21 | worksheet = _config.get('Lab Config Sheet', 'worksheet') 22 | 23 | instance_data_dir = _config.get('Instances', 'instance_data_dir') 24 | docker_control_url = _config.get('Instances', 'docker_control_url') 25 | sourcecode_repo = _config.get('Instances', 'sourcecode_repo') 26 | docker_image = _config.get('Instances', 'docker_image') 27 | -------------------------------------------------------------------------------- /lab-server/controller/lsc/model/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/lab-server/controller/lsc/model/__init__.py -------------------------------------------------------------------------------- /lab-server/controller/lsc/shell.py: -------------------------------------------------------------------------------- 1 | '''The Lab Server Controller is a command line tool that helps manage 2 | the lab server used for teaching the CoderDojo TC's Python-Minecraft 3 | code group. 4 | 5 | ''' 6 | 7 | # This script uses the Cliff framework. It is installed and configured 8 | # through the package's setup.py file, so check the entry_points defined 9 | # there. 10 | 11 | 12 | import logging 13 | import sys 14 | 15 | from cliff.app import App 16 | from cliff.commandmanager import CommandManager 17 | import lsc 18 | 19 | 20 | class LabServerControllerApp(App): 21 | 22 | log = logging.getLogger(__name__) 23 | 24 | def __init__(self): 25 | super(LabServerControllerApp, self).__init__( 26 | description=__doc__.strip(), 27 | version=lsc.__version__, 28 | command_manager=CommandManager('lab_server_controller'), 29 | ) 30 | 31 | 32 | def configure_logging(self): 33 | ''' Override the console logging to our preferences 34 | ''' 35 | if self.options.debug: 36 | self.CONSOLE_MESSAGE_FORMAT = '%(asctime)s %(levelname)-8s %(name)s\t%(message)s' 37 | else: 38 | self.CONSOLE_MESSAGE_FORMAT = '%(levelname)-8s %(name)s %(message)s' 39 | 40 | # Pick up any default initializations 41 | super(LabServerControllerApp, self).configure_logging() 42 | 43 | 44 | def initialize_app(self, argv): 45 | """ Application initialization code 46 | """ 47 | 48 | # Pick up any default initializations 49 | super(LabServerControllerApp, self).initialize_app(argv) 50 | 51 | if self.options.debug: 52 | self.dump_stack_trace = True 53 | else: 54 | self.dump_stack_trace = False 55 | 56 | self.log.debug('initialize_app') 57 | 58 | 59 | def prepare_to_run_command(self, cmd): 60 | self.log.debug('prepare_to_run_command %s', cmd.__class__.__name__) 61 | 62 | 63 | def clean_up(self, cmd, result, err): 64 | self.log.debug('clean_up %s', cmd.__class__.__name__) 65 | if err: 66 | self.log.debug('got an error: %s', err) 67 | 68 | 69 | def main(argv=sys.argv[1:]): 70 | return LabServerControllerApp().run(argv) 71 | 72 | 73 | if __name__ == '__main__': 74 | sys.exit(main(sys.argv[1:])) 75 | -------------------------------------------------------------------------------- /lab-server/controller/requirements.txt: -------------------------------------------------------------------------------- 1 | cffi==1.1.2 2 | cliff-tablib==1.1 3 | cliff==1.7.0 4 | cryptography==0.9.1 5 | csvkit==0.9.0 6 | docker-py==0.6.0 7 | gspread==0.2.5 8 | oauth2client==1.4.11 9 | pyOpenSSL==0.15.1 10 | -------------------------------------------------------------------------------- /lab-server/controller/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import lsc 4 | 5 | from setuptools import setup, find_packages 6 | 7 | try: 8 | long_description = open('README.rst', 'rt').read() 9 | except IOError: 10 | long_description = '' 11 | 12 | 13 | setup( 14 | name='lsc', 15 | version=lsc.__version__, 16 | packages=find_packages(), 17 | 18 | description='CoderDojo Twin Cities, Python-Minecraft, Lab Server Controller', 19 | long_description=long_description, 20 | 21 | author='Mike McCallister', 22 | author_email='mike@mccllstr.com', 23 | 24 | classifiers=[ 25 | 'Development Status :: 2 - Pre-Alpha', 26 | 'Environment :: Console', 27 | 'Intended Audience :: Information Technology', 28 | 'License :: OSI Approved :: MIT License', 29 | 'Operating System :: OS Independent', 30 | 'Programming Language :: Python', 31 | 'Programming Language :: Python :: 2', 32 | 'Programming Language :: Python :: 2.7', 33 | ], 34 | 35 | platforms=['Any'], 36 | 37 | install_requires=[ 38 | 'cliff', 39 | 'cliff-tablib', 40 | 'docker-py', 41 | 'gspread', 42 | 'csvkit', 43 | ], 44 | 45 | entry_points={ 46 | 'console_scripts': [ 47 | 'lsc = lsc.shell:main', 48 | ], 49 | 50 | 'lab_server_controller': [ 51 | 'test = lsc.commands.environment:Test', 52 | 53 | 'show = lsc.commands.lab:Show', 54 | 55 | 'process-commands = lsc.commands.lab:ProcessCommands', 56 | ], 57 | 58 | 'cliff.formatter.list': [ 59 | 'unicsv = cliffuni.formatters:UniCsvFormatter', 60 | ], 61 | 62 | 'cliff.formatter.show': [ 63 | 'unicsv = cliffuni.formatters:UniCsvFormatter', 64 | ], 65 | }, 66 | ) 67 | -------------------------------------------------------------------------------- /lab-server/lab-server-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/dash -e 2 | 3 | # This script sets up a lab server for hosting student environments 4 | # for the python-minecraft code group. 5 | # 6 | # It is intended to be used as a provisioning script by Vagrant. The 7 | # provided Vagrantfile invokes this script after creating a vanilla 8 | # box running Ubuntu Trusty (14.04 LTS) as its base image. 9 | # 10 | # The resulting box will have: 11 | # 12 | # * Docker installed. Docker is used for hosting the student 13 | # environments. You will need to pull in a student image from a 14 | # Docker registry, or follow the instructions in the 15 | # :file:`student-env-image` folder to build one locally. 16 | # 17 | # * The Lab Server Controller and its pre-dependencies will be 18 | # installed. 19 | # 20 | # * The :command:`mcrcon` command will be compiled from source and 21 | # installed so that the Lab Server Controller can send commands to 22 | # the running Minecraft server instances. 23 | 24 | # ---------------------------------------------------------------------------- 25 | # Semi-configurable options 26 | 27 | LAB_USER=vagrant 28 | 29 | 30 | # ---------------------------------------------------------------------------- 31 | # Add the official Docker repository 32 | 33 | apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 34 | echo deb https://get.docker.com/ubuntu docker main >/etc/apt/sources.list.d/docker.list 35 | 36 | 37 | # ---------------------------------------------------------------------------- 38 | # Install pre-dependencies available in Ubuntu itself 39 | 40 | apt-get update 41 | apt-get -y upgrade 42 | 43 | # Install tools used by this setup script. 44 | # 45 | # `haveged` is used to make sure the box has enough entropy to 46 | # generate good random numbers without stalling. 47 | # 48 | # `apg` is used to generate passwords. 49 | # 50 | # `python-pip` is used to create the environment in which the Lab 51 | # Sever Controller runs. 52 | apt-get -y install apg haveged python-pip 53 | 54 | 55 | # ---------------------------------------------------------------------------- 56 | # Install Docker 57 | 58 | apt-get -y install lxc-docker 59 | 60 | 61 | # ---------------------------------------------------------------------------- 62 | # Install the Lab Server Controller 63 | 64 | cd /vagrant/controller 65 | pip install -r requirements.txt 66 | pip install -e . 67 | 68 | # Install the mcrcon command so we can send commands to the running 69 | # Minecraft servers with RCON. 70 | 71 | cd /home/${LAB_USER} 72 | if [ ! -d mcrcon ]; then 73 | git clone https://github.com/Tiiffi/mcrcon 74 | fi 75 | cd mcrcon 76 | gcc -std=gnu99 -pedantic -Wall -Wextra -O2 -s -o /usr/local/bin/mcrcon mcrcon.c 77 | 78 | 79 | # ---------------------------------------------------------------------------- 80 | # Clean up and exit 81 | 82 | # Link the user's bin directory to the /vagrant/user-commands so that 83 | # they will be found in the user's path, and are easy to invoke like: 84 | # vagrant ssh -c COMMAND 85 | #ln -s /vagrant/user-commands /home/${LAB_USER}/bin 86 | 87 | # Fix up permissions 88 | chown -R ${LAB_USER}:${LAB_USER} /home/${LAB_USER} 89 | 90 | # Tell the user what to do next. 91 | cat < 6 | 7 | # ---------------------------------------------------------------------------- 8 | # Pull in the components we need from Ubuntu. This is done here 9 | # instead of in the server setup script because it lets Docker take 10 | # advantage of its cache, which greatly speeds up subsequent builds. 11 | 12 | RUN apt-get update \ 13 | && apt-get install --no-install-recommends --no-install-suggests -y \ 14 | apg \ 15 | curl \ 16 | git-core \ 17 | haveged \ 18 | ipython-notebook \ 19 | openjdk-7-jre-headless \ 20 | openssl \ 21 | psmisc \ 22 | python-imaging \ 23 | python-pip \ 24 | python-pygame \ 25 | supervisor \ 26 | tmux \ 27 | unison \ 28 | unzip \ 29 | zip \ 30 | && apt-get clean \ 31 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 32 | 33 | # Upgrade IPython to get improved usability of the Notebook server 34 | RUN pip install --upgrade jsonschema==2.4.0 tornado==4.0.0 ipython==3.1.0 35 | 36 | 37 | # ---------------------------------------------------------------------------- 38 | # Minor configurations 39 | 40 | # Set up Supervisor to run the pieces of the student's environment 41 | COPY minecraft-lab.conf /etc/supervisor/conf.d/minecraft-lab.conf 42 | 43 | # Copy our convenience commands into the image 44 | COPY commands/ /usr/local/bin 45 | 46 | # Expose the ports for the IPython notebook server and Minecraft 47 | EXPOSE 8888 48 | EXPOSE 25565 49 | 50 | # Set the default command when a container is run 51 | CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"] 52 | 53 | # Set up the student user 54 | RUN ["adduser", "student", "--disabled-password", "--disabled-login", "--gecos", ""] 55 | 56 | 57 | # ---------------------------------------------------------------------------- 58 | # Prepare the image to run the Canary (Minecraft) Server 59 | 60 | # Copy the default Canary configuration/files/world into the image 61 | 62 | # NOTE: the contents of the following directory can be recreated with 63 | # the following commands: 64 | # 65 | # rm -rf server-files/* 66 | # cd server-files 67 | # java -jar CANARY_JAR_FILE nogui 68 | # 69 | # Then, make the necessary edits by hand. Do this if the Canary 70 | # version moves ahead far enough that we need to create new default 71 | # configuration files. 72 | 73 | COPY default-canary-files/ /usr/local/share/default-canary-files/ 74 | 75 | # Get a copy of the RaspberryJuice plugin from GitHub 76 | 77 | ADD https://github.com/martinohanlon/CanaryRaspberryJuice/blob/master/jars/canaryraspberryjuice-1.3.jar?raw=true /usr/local/share/default-canary-files/plugins/ 78 | 79 | # Download the Canary jar file 80 | 81 | #ADD https://ci.visualillusionsent.net/job/CanaryMod/805/artifact/target/CanaryMod-1.8.0-1.2.1-SNAPSHOT-shaded.jar /usr/local/bin/ 82 | ADD http://canarymod.net/releases/CanaryMod-1.2.0.jar /usr/local/bin/CanaryMod-1.8.0-1.2.0-shaded.jar 83 | -------------------------------------------------------------------------------- /lab-server/student-env-image/README.rst: -------------------------------------------------------------------------------- 1 | =========================================== 2 | Working With Docker Images and Containers 3 | =========================================== 4 | 5 | Some quick notes so I don't lose this with my command history. 6 | 7 | To build the python-minecraft-student image from the docker file:: 8 | 9 | sudo docker build -t "coderdojotc.org/python-minecraft-student" . 10 | 11 | To start a container running the python-minecraft-student image:: 12 | 13 | sudo docker run -P -i -t coderdojotc.org/python-minecraft-student su - vagrant -c /bin/bash 14 | 15 | Once at the bash prompt inside the container, issue the 16 | :command:`start-env.sh` command to bring up the Minecraft and IPython 17 | servers. 18 | 19 | 20 | To Run a Student Instance 21 | ========================= 22 | 23 | The idiomatic way to configure Docker containers is to pass 24 | environment variables into the :command:`docker run` command. In 25 | practice, this is roughly what will happen to kick off a student 26 | instance: 27 | 28 | #. Create a Docker Data Volume Container to hold the student's files:: 29 | 30 | mkdir /tmp/student-AAAA-datadir # Or something more permanent 31 | sudo docker run -d --name student-AAAA-data ubuntu:14.04 echo Data-only container for Student AAAA 32 | 33 | #. Launch a container based on the student image:: 34 | 35 | sudo docker run -d \ 36 | -v /tmp/student-AAAA-datadir:/home/student/minecraft-lab \ 37 | -e "MOJANG_ACCOUNTS=#####" \ 38 | -e "STUDENT_PASSWORD=####" \ 39 | -e "CODERDOJO_REPO=https://github.com/mikemccllstr/mikemccllstr-python-minecraft.git" \ 40 | -e "SERVER_DNS_NAME=____" \ 41 | -p 10443:8888 -p 10565:25565 \ 42 | coderdojotc.org/python-minecraft-student 43 | -------------------------------------------------------------------------------- /lab-server/student-env-image/commands/run-canary.sh: -------------------------------------------------------------------------------- 1 | #!/bin/dash -e 2 | 3 | # This script should be run by Supervisor to start up a Canary server 4 | # instance (Minecraft server) to support the python-minecraft lab 5 | # activities. It is configured through environment variables which get 6 | # passed in from the `docker run` command line. 7 | 8 | # ---------------------------------------------------------------------------- 9 | # Determine a few things 10 | 11 | LAB_USER=student 12 | MINECRAFT_LAB=/home/${LAB_USER}/minecraft-lab 13 | 14 | 15 | # ---------------------------------------------------------------------------- 16 | # Copy the necessary files into place 17 | 18 | if [ ! -d ${MINECRAFT_LAB}/server-files ]; then 19 | mkdir -p ${MINECRAFT_LAB} 20 | cp -pr /usr/local/share/default-canary-files ${MINECRAFT_LAB}/server-files 21 | 22 | # Fix up permissions 23 | chown -R ${LAB_USER}:${LAB_USER} ${MINECRAFT_LAB}/server-files 24 | fi 25 | 26 | # Open up permissions on the Canary jar 27 | chmod go+r /usr/local/bin/CanaryMod-*.jar 28 | 29 | 30 | # ---------------------------------------------------------------------------- 31 | # Start the server 32 | 33 | # Op the users 34 | echo ${MOJANG_ACCOUNTS} | perl -pe "s{,}{\n}g" >>${MINECRAFT_LAB}/server-files/config/ops.cfg 35 | 36 | cd ${MINECRAFT_LAB}/server-files 37 | chown -R ${LAB_USER}:${LAB_USER} . 38 | 39 | SESSION_NAME=minecraft 40 | 41 | tmux new-session -d -s ${SESSION_NAME} -n minecraft "su ${LAB_USER} -c \"java -Xincgc -Xmx1G -jar /usr/local/bin/CanaryMod-*.jar nogui\"; tmux wait-for -S minecraft-out" 42 | 43 | # Wait for server to start 44 | sleep 5 45 | while ! (tmux capture-pane \; save-buffer - |grep -q Done) && killall -0 java ; do 46 | sleep 1 47 | done 48 | 49 | # Do some server configuration 50 | tmux send-keys -t ${SESSION_NAME} 'gamerule doMobSpawning false' C-m 51 | tmux send-keys -t ${SESSION_NAME} 'gamerule doDaylightCycle false' C-m 52 | tmux send-keys -t ${SESSION_NAME} 'time set 1000' C-m 53 | tmux send-keys -t ${SESSION_NAME} 'defaultgamemode 1' C-m 54 | tmux send-keys -t ${SESSION_NAME} 'weather clear 999999' C-m 55 | 56 | # Check for receipt of signals indicating we should exit. Send the 57 | # 'stop' command to Canary if we get one. 58 | trap "tmux send-keys -t ${SESSION_NAME} stop C-m" TERM INT QUIT 59 | 60 | # -- DIRTY HACK WARNING ------------------------------------------------------ 61 | 62 | # NOTE: This is a dirty hack. For some reason, Canary is failing to 63 | # determine the UUID of the players listed in ops.txt on startup, so 64 | # I've had to put this reactive code here to do the job after the 65 | # player joins the server. 66 | 67 | sleep 10 68 | while ! ( grep -iq "\[INFO\]: ${MOJANG_ACCOUNTS} joined the game" ${MINECRAFT_LAB}/server-files/logs/latest.log && tmux send-keys -t ${SESSION_NAME} "op ${MOJANG_ACCOUNTS}" C-m ) ; do 69 | tmux send-keys -t ${SESSION_NAME} "say Waiting for ${MOJANG_ACCOUNTS} to join the game..." C-m 70 | sleep 5 71 | done 72 | # -- DIRTY HACK WARNING ------------------------------------------------------ 73 | 74 | # Pause here until the original session kicks out the "minecraft-out" 75 | # signal (generated with the tmux wait-for -S). 76 | tmux wait-for minecraft-out 77 | -------------------------------------------------------------------------------- /lab-server/student-env-image/commands/run-ipython-notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/dash -e 2 | 3 | # This script should be run by Supervisor to start up an IPython 4 | # notebook environment to support the python-minecraft lab 5 | # activities. It is configured through environment variables which get 6 | # passed in from the `docker run` command line. 7 | 8 | # ---------------------------------------------------------------------------- 9 | # Determine a few things 10 | 11 | LAB_USER=student 12 | MINECRAFT_LAB=/home/${LAB_USER}/minecraft-lab 13 | 14 | 15 | # ---------------------------------------------------------------------------- 16 | # Configure IPython 17 | 18 | # Create the profile and a cert 19 | su - ${LAB_USER} -c "ipython profile create nbserver --reset" 20 | 21 | if [ ! -f /home/${LAB_USER}/.ipython/profile_nbserver/ipython-cert.pem ]; then 22 | cd /home/${LAB_USER}/.ipython/profile_nbserver/ 23 | TMP_FILE=$(mktemp --tmpdir=$PWD) 24 | chmod go-rwx ${TMP_FILE} 25 | mv ${TMP_FILE} ipython-cert.pem 26 | chown ${LAB_USER}:${LAB_USER} ipython-cert.pem 27 | openssl req -x509 -subj "/C=US/ST=MN/L=Twin Cities/O=CoderDojoTC/CN=localhost" -nodes -days 365 -newkey rsa:1024 -keyout ipython-cert.pem -out ipython-cert.pem 28 | else 29 | echo ipython-cert.pem already exists, preserving existing file 30 | fi 31 | 32 | # Hash the password 33 | PASSWORD_HASH=$(python -c "import IPython.lib.security; print IPython.lib.security.passwd('${STUDENT_PASSWORD}')") 34 | 35 | # Create the config file 36 | cat >/home/${LAB_USER}/.ipython/profile_nbserver/ipython_notebook_config.py <} 6 | # Examples: {permission:canary.super.administor} {permission:canary.world.build&!canary.super.administrator} 7 | # # # # # 8 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/config/ops.cfg: -------------------------------------------------------------------------------- 1 | # Note: This file is not guaranteed to be synchronous with the actual ops list in database. 2 | # However, you may use it to quickly add new operators as you please. 3 | # Any duplicate entries will be taken care of so don't worry. 4 | # Lines starting with # are comments ;) 5 | # Add one name to each line. 6 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/config/server.cfg: -------------------------------------------------------------------------------- 1 | ;Sets whether to inform all of a Player's Achievement 2 | announce-player-achievements=true 3 | ;Sets whether to allow items with enchantments to stack with non-enchanted items 4 | allow-enchantment-stacking=false 5 | ;The default message to use for user bans 6 | ban-default-message=You are banned from this server. 7 | ;The message to prefix to the timestamp of a tempban expiration 8 | ban-expiration-date-message=Your Ban will be lifted at 9 | ;Valid default placeholders are: 10 | ;%prefix (player prefix), %name (player name), %group (main group) 11 | ;You can use standard color codes at all times. Use & as identifier if you miss a § key 12 | ;Plugins may extend the list of available placeholders 13 | chat-format=<%prefix%name&f> %message 14 | ;Sets whether the Command Block is allowed or not 15 | command-block-enabled=false 16 | ;This groups permissions will determine what Command Block can and can not do! 17 | command-block-group=default 18 | ;Sets whether the Command Block is considered Operator or not (Vanilla command use) 19 | command-block-op=false 20 | ;The Datasource type to use (Default available: xml, mysql, sqlite 21 | data-source=xml 22 | ;A formatting to display timestamps 23 | date-format=yyyy.MM.dd, hh:mm:ss 24 | ;Sets whether to send player death message or not 25 | death-messages=true 26 | ;Name of the default loaded world 27 | default-world-name=default 28 | ;Sets the level of logging. 29 | ;Acceptable Values: OFF FATAL ERROR WARN INFO DEBUG TRACE ALL 30 | logger-level=INFO 31 | ;The maximum allowed players online (Does not count ReserveList users connecting after server is full) 32 | max-players=20 33 | ;The Server list Message of the Day 34 | motd=CanaryMod Minecraft Server 35 | ;Sets whether to authenticate connecting users. 36 | ;WARNING: Setting to false is INSECURE and should not be done in a production environment 37 | online-mode=true 38 | ;Timeout in minutes before kicking an idle player 39 | player-idle-timeout=15 40 | ;Sets whether to send data to clients for the Player List 41 | playerlist-enabled=true 42 | ;Sets whether the Player List should automatically be refreshed for every player or not 43 | playerlist-autoupdate=true 44 | ;Sets whether the Player List should include colors and player prefixes 45 | playerlist-usecolors=false 46 | playerlist-ticks=500 47 | ;Enables GameSpy4 protocol server listener. Used to get information about server. 48 | query-enabled=false 49 | ;Set the port for the query server 50 | query-port=25565 51 | ;Whether to allow remote access or not 52 | rcon-enabled=false 53 | ;The port you want remote access to listen on (1-65534), DEFAULT: 25575 54 | rcon-port=25575 55 | ;Password for remote access 56 | rcon-password= 57 | ;Sets whether the ReserveList (join after full) is enabled or not 58 | reservelist-enabled=false 59 | reservelist-message=Not on reserve list. 60 | ;Sets whether to save homes or not 61 | save-homes=true 62 | ;Message to send if the server is full 63 | server-full-message=The server is full. 64 | ;Set to the IP address that you want your server to listen on, or leave blank for automatic detection. 65 | server-ip= 66 | ;The Port you want your server to listen on (1-65534), DEFAULT: 25565 67 | server-port=25565 68 | ;Sets the default server language to use for messages. Default supported Languages can be found in the lang/languages.txt 69 | server-locale=en_US 70 | ;Sets whether to inform players of unknown commands 71 | show-unknown-command=true 72 | ;Sets whether Mojang may snoop or not 73 | snooper-enabled=true 74 | ;Level of protection against Spam. Options: default - on for all but ignorerestiction users; off - no protections; all - on for all 75 | spam-protection=default 76 | ;Sets whether to strictly check characters on signs for invalid chat characters. Set to false to disable (and allow more characters) 77 | strict-sign-characters=true 78 | ;The name of the Server's texture/resource pack 79 | texture-pack= 80 | update-lang-files=true 81 | ;Sets the maximum radius of loaded chunks around a player (3-15) 82 | view-distance=10 83 | ;Whether the whitelist is enabled or not 84 | whitelist-enabled=false 85 | ;The message to send to non-whitelisted players 86 | whitelist-message=Not on whitelist. 87 | ;Enable automatic unloading of unused worlds. 88 | world-cache-timer-enabled=true 89 | ;For how long should a world be empty before it will be unloaded (if use-world-cache is enabled) 90 | world-cache-timeout=60 91 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/config/worlds/default/default_NORMAL.cfg: -------------------------------------------------------------------------------- 1 | world-name=default_NORMAL 2 | world-type=FLAT 3 | spawn-protection=16 4 | max-build-height=256 5 | generate-structures=false 6 | generator-settings= 7 | world-seed=-7848771616304129336 8 | startup-autoload=false 9 | warp-autoload=false 10 | allow-nether=true 11 | allow-end=true 12 | allow-flight=true 13 | pvp=true 14 | difficulty=1 15 | gamemode=0 16 | forceDefaultGameMode=true 17 | forceDefaultGameModeDimensional=false 18 | auto-heal=default 19 | enable-experience=false 20 | enable-health=true 21 | spawn-villagers=false 22 | spawn-golems=false 23 | spawn-animals=false 24 | spawn-monsters=false 25 | natural-animals=Bat,Chicken,Cow,Mooshroom,Ocelot,Pig,Sheep,Wolf,Horse 26 | natural-monsters=Enderman,PigZombie,Blaze,CaveSpider,Creeper,Ghast,MagamaCube,Silverfish,Skeleton,Slime,Spider,Witch,Zombie,Wither,EnderDragon,GiantZombie 27 | natural-golems=IronGolem,Snowman 28 | natural-wateranimals=Squid 29 | natural-spawn-rate=100 30 | ender-blocks=2,3,12,13,37,38,39,40,46,81,82,86,103,110 31 | disallowed-blocks=7,8,9,10,11,46,51,52 32 | 33 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/db/ban.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/db/operators.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/db/permission.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/db/reservelist.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/db/whitelist.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/eula.txt: -------------------------------------------------------------------------------- 1 | #By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula). 2 | #Tue Nov 11 16:08:24 CST 2014 3 | eula=true 4 | -------------------------------------------------------------------------------- /lab-server/student-env-image/default-canary-files/worlds/scoreboards/session.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/lab-server/student-env-image/default-canary-files/worlds/scoreboards/session.lock -------------------------------------------------------------------------------- /lab-server/student-env-image/minecraft-lab.conf: -------------------------------------------------------------------------------- 1 | # This is the Supervisor configuration file for the processes that 2 | # make up the minecraft-lab 3 | 4 | [supervisord] 5 | nodaemon=true 6 | 7 | [program:ipython] 8 | command=/usr/local/bin/run-ipython-notebook.sh 9 | 10 | [program:canary] 11 | command=/usr/local/bin/run-canary.sh 12 | stopasgroup=true 13 | -------------------------------------------------------------------------------- /mcpi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/mcpi/__init__.py -------------------------------------------------------------------------------- /mcpi/block.py: -------------------------------------------------------------------------------- 1 | class Block: 2 | """Minecraft PI block description. Can be sent to Minecraft.setBlock/s""" 3 | def __init__(self, id, data=0): 4 | self.id = id 5 | self.data = data 6 | 7 | def __cmp__(self, rhs): 8 | return hash(self) - hash(rhs) 9 | 10 | def __hash__(self): 11 | return (self.id << 8) + self.data 12 | 13 | def withData(self, data): 14 | return Block(self.id, data) 15 | 16 | def __iter__(self): 17 | """Allows a Block to be sent whenever id [and data] is needed""" 18 | return iter((self.id, self.data)) 19 | 20 | def __repr__(self): 21 | return "Block(%d, %d)"%(self.id, self.data) 22 | 23 | AIR = Block(0) 24 | STONE = Block(1) 25 | GRASS = Block(2) 26 | DIRT = Block(3) 27 | COBBLESTONE = Block(4) 28 | WOOD_PLANKS = Block(5) 29 | SAPLING = Block(6) 30 | BEDROCK = Block(7) 31 | WATER_FLOWING = Block(8) 32 | WATER = WATER_FLOWING 33 | WATER_STATIONARY = Block(9) 34 | LAVA_FLOWING = Block(10) 35 | LAVA = LAVA_FLOWING 36 | LAVA_STATIONARY = Block(11) 37 | SAND = Block(12) 38 | GRAVEL = Block(13) 39 | GOLD_ORE = Block(14) 40 | IRON_ORE = Block(15) 41 | COAL_ORE = Block(16) 42 | WOOD = Block(17) 43 | LEAVES = Block(18) 44 | GLASS = Block(20) 45 | LAPIS_LAZULI_ORE = Block(21) 46 | LAPIS_LAZULI_BLOCK = Block(22) 47 | SANDSTONE = Block(24) 48 | BED = Block(26) 49 | COBWEB = Block(30) 50 | GRASS_TALL = Block(31) 51 | WOOL = Block(35) 52 | FLOWER_YELLOW = Block(37) 53 | FLOWER_CYAN = Block(38) 54 | MUSHROOM_BROWN = Block(39) 55 | MUSHROOM_RED = Block(40) 56 | GOLD_BLOCK = Block(41) 57 | IRON_BLOCK = Block(42) 58 | STONE_SLAB_DOUBLE = Block(43) 59 | STONE_SLAB = Block(44) 60 | BRICK_BLOCK = Block(45) 61 | TNT = Block(46) 62 | BOOKSHELF = Block(47) 63 | MOSS_STONE = Block(48) 64 | OBSIDIAN = Block(49) 65 | TORCH = Block(50) 66 | FIRE = Block(51) 67 | STAIRS_WOOD = Block(53) 68 | CHEST = Block(54) 69 | DIAMOND_ORE = Block(56) 70 | DIAMOND_BLOCK = Block(57) 71 | CRAFTING_TABLE = Block(58) 72 | FARMLAND = Block(60) 73 | FURNACE_INACTIVE = Block(61) 74 | FURNACE_ACTIVE = Block(62) 75 | DOOR_WOOD = Block(64) 76 | LADDER = Block(65) 77 | STAIRS_COBBLESTONE = Block(67) 78 | DOOR_IRON = Block(71) 79 | REDSTONE_ORE = Block(73) 80 | SNOW = Block(78) 81 | ICE = Block(79) 82 | SNOW_BLOCK = Block(80) 83 | CACTUS = Block(81) 84 | CLAY = Block(82) 85 | SUGAR_CANE = Block(83) 86 | FENCE = Block(85) 87 | GLOWSTONE_BLOCK = Block(89) 88 | BEDROCK_INVISIBLE = Block(95) 89 | STONE_BRICK = Block(98) 90 | GLASS_PANE = Block(102) 91 | MELON = Block(103) 92 | FENCE_GATE = Block(107) 93 | GLOWING_OBSIDIAN = Block(246) 94 | NETHER_REACTOR_CORE = Block(247) 95 | -------------------------------------------------------------------------------- /mcpi/connection.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import select 3 | import sys 4 | from util import flatten_parameters_to_string 5 | 6 | """ @author: Aron Nieminen, Mojang AB""" 7 | 8 | class RequestError(Exception): 9 | pass 10 | 11 | class Connection: 12 | """Connection to a Minecraft Pi game""" 13 | RequestFailed = "Fail" 14 | 15 | def __init__(self, address, port): 16 | self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 | self.socket.connect((address, port)) 18 | self.lastSent = "" 19 | 20 | def drain(self): 21 | """Drains the socket of incoming data""" 22 | while True: 23 | readable, _, _ = select.select([self.socket], [], [], 0.0) 24 | if not readable: 25 | break 26 | data = self.socket.recv(1500) 27 | e = "Drained Data: <%s>\n"%data.strip() 28 | e += "Last Message: <%s>\n"%self.lastSent.strip() 29 | sys.stderr.write(e) 30 | 31 | def send(self, f, *data): 32 | """Sends data. Note that a trailing newline '\n' is added here""" 33 | s = "%s(%s)\n"%(f, flatten_parameters_to_string(data)) 34 | #print "f,data:",f,data 35 | #print "s",s 36 | self.drain() 37 | self.lastSent = s 38 | self.socket.sendall(s) 39 | 40 | def receive(self): 41 | """Receives data. Note that the trailing newline '\n' is trimmed""" 42 | s = self.socket.makefile("r").readline().rstrip("\n") 43 | if s == Connection.RequestFailed: 44 | raise RequestError("%s failed"%self.lastSent.strip()) 45 | return s 46 | 47 | def sendReceive(self, *data): 48 | """Sends and receive data""" 49 | self.send(*data) 50 | return self.receive() 51 | -------------------------------------------------------------------------------- /mcpi/event.py: -------------------------------------------------------------------------------- 1 | from vec3 import Vec3 2 | 3 | class BlockEvent: 4 | """An Event related to blocks (e.g. placed, removed, hit)""" 5 | HIT = 0 6 | 7 | def __init__(self, type, x, y, z, face, entityId): 8 | self.type = type 9 | self.pos = Vec3(x, y, z) 10 | self.face = face 11 | self.entityId = entityId 12 | 13 | def __repr__(self): 14 | sType = { 15 | BlockEvent.HIT: "BlockEvent.HIT" 16 | }.get(self.type, "???") 17 | 18 | return "BlockEvent(%s, %d, %d, %d, %d, %d)"%( 19 | sType,self.pos.x,self.pos.y,self.pos.z,self.face,self.entityId); 20 | 21 | @staticmethod 22 | def Hit(x, y, z, face, entityId): 23 | return BlockEvent(BlockEvent.HIT, x, y, z, face, entityId) 24 | 25 | class ChatEvent: 26 | """An Event related to chat (e.g. posts)""" 27 | POST = 0 28 | 29 | def __init__(self, type, entityId, message): 30 | self.type = type 31 | self.entityId = entityId 32 | self.message = message 33 | 34 | def __repr__(self): 35 | sType = { 36 | ChatEvent.POST: "ChatEvent.POST" 37 | }.get(self.type, "???") 38 | 39 | return "ChatEvent(%s, %d, %s)"%( 40 | sType,self.entityId,self.message); 41 | 42 | @staticmethod 43 | def Post(entityId, message): 44 | return ChatEvent(ChatEvent.POST, entityId, message) 45 | 46 | -------------------------------------------------------------------------------- /mcpi/util.py: -------------------------------------------------------------------------------- 1 | import collections 2 | 3 | def flatten(l): 4 | for e in l: 5 | if isinstance(e, collections.Iterable) and not isinstance(e, basestring): 6 | for ee in flatten(e): yield ee 7 | else: yield e 8 | 9 | def flatten_parameters_to_string(l): 10 | return ",".join(map(str, flatten(l))) 11 | -------------------------------------------------------------------------------- /mcpi/vec3.py: -------------------------------------------------------------------------------- 1 | class Vec3: 2 | def __init__(self, x=0, y=0, z=0): 3 | self.x = x 4 | self.y = y 5 | self.z = z 6 | 7 | def __add__(self, rhs): 8 | c = self.clone() 9 | c += rhs 10 | return c 11 | 12 | def __iadd__(self, rhs): 13 | self.x += rhs.x 14 | self.y += rhs.y 15 | self.z += rhs.z 16 | return self 17 | 18 | def length(self): 19 | return self.lengthSqr ** .5 20 | 21 | def lengthSqr(self): 22 | return self.x * self.x + self.y * self.y + self.z * self.z 23 | 24 | def __mul__(self, k): 25 | c = self.clone() 26 | c *= k 27 | return c 28 | 29 | def __imul__(self, k): 30 | self.x *= k 31 | self.y *= k 32 | self.z *= k 33 | return self 34 | 35 | def clone(self): 36 | return Vec3(self.x, self.y, self.z) 37 | 38 | def __neg__(self): 39 | return Vec3(-self.x, -self.y, -self.z) 40 | 41 | def __sub__(self, rhs): 42 | return self.__add__(-rhs) 43 | 44 | def __isub__(self, rhs): 45 | return self.__iadd__(-rhs) 46 | 47 | def __repr__(self): 48 | return "Vec3(%s,%s,%s)"%(self.x,self.y,self.z) 49 | 50 | def __iter__(self): 51 | return iter((self.x, self.y, self.z)) 52 | 53 | def _map(self, func): 54 | self.x = func(self.x) 55 | self.y = func(self.y) 56 | self.z = func(self.z) 57 | 58 | def __cmp__(self, rhs): 59 | dx = self.x - rhs.x 60 | if dx != 0: return dx 61 | dy = self.y - rhs.y 62 | if dy != 0: return dy 63 | dz = self.z - rhs.z 64 | if dz != 0: return dz 65 | return 0 66 | 67 | def iround(self): self._map(lambda v:int(v+0.5)) 68 | def ifloor(self): self._map(int) 69 | 70 | def rotateLeft(self): self.x, self.z = self.z, -self.x 71 | def rotateRight(self): self.x, self.z = -self.z, self.x 72 | 73 | def testVec3(): 74 | # Note: It's not testing everything 75 | 76 | # 1.1 Test initialization 77 | it = Vec3(1, -2, 3) 78 | assert it.x == 1 79 | assert it.y == -2 80 | assert it.z == 3 81 | 82 | assert it.x != -1 83 | assert it.y != +2 84 | assert it.z != -3 85 | 86 | # 2.1 Test cloning and equality 87 | clone = it.clone() 88 | assert it == clone 89 | it.x += 1 90 | assert it != clone 91 | 92 | # 3.1 Arithmetic 93 | a = Vec3(10, -3, 4) 94 | b = Vec3(-7, 1, 2) 95 | c = a + b 96 | assert c - a == b 97 | assert c - b == a 98 | assert a + a == a * 2 99 | 100 | assert a - a == Vec3(0,0,0) 101 | assert a + (-a) == Vec3(0,0,0) 102 | 103 | # Test repr 104 | e = eval(repr(it)) 105 | assert e == it 106 | 107 | if __name__ == "__main__": 108 | testVec3() 109 | -------------------------------------------------------------------------------- /mcpiext/LICENSE-minecraft-stuff: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 2 | 3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6 | -------------------------------------------------------------------------------- /mcpiext/LICENSE-minecraft-turtle: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 2 | 3 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 6 | -------------------------------------------------------------------------------- /mcpiext/README-minecraft-stuff.md: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Minecraft - Stuff Library 3 | Martin O'Hanlon (martin@ohanlonweb.com) 4 | http://www.stuffaboutcode.com 5 | ------------------------------------------------------------------------------- 6 | 7 | An extension library of useful 'stuff' (aka classes) I have created for 8 | Minecraft: Pi Edition's API. It provides functions for drawing lines 9 | and other objects 10 | 11 | ------------------------------------------------------------------------------ 12 | 13 | Version history 14 | 0.1 - first beta release, MinecraftDrawing class 15 | 0.2 - extended with new drawing functions and MinecraftShapes class 16 | 0.3 - included DrawHollowSphere function 17 | 18 | ------------------------------------------------------------------------------- 19 | -------------------------------------------------------------------------------- /mcpiext/README-minecraft-turtle.md: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Minecraft - Turtle Library 3 | Martin O'Hanlon (martin@ohanlonweb.com) 4 | http://www.stuffaboutcode.com 5 | http://www.stuffaboutcode.com/2014/05/minecraft-graphics-turtle.html 6 | ------------------------------------------------------------------------------- 7 | A 3d grapics turtle for Minecraft: Pi edition. 8 | ------------------------------------------------------------------------------ 9 | 10 | Version history 11 | 0.1 - first beta release 12 | 0.2 - bug fixes, new examples 13 | 14 | ------------------------------------------------------------------------------- 15 | -------------------------------------------------------------------------------- /mcpiext/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CoderDojoTC/python-minecraft/d78ff6d30e47b887f5db12f23de81dd716576c0b/mcpiext/__init__.py -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # This is a Pip requirements file. Use it to install the Python tools 2 | # needed to develop and support the python-minecraft course as follows: 3 | # 4 | # virtualenv .env 5 | # pip install --upgrade -r requirements.txt 6 | 7 | Fabric==1.10.1 8 | docker-py==1.2.3-rc1 9 | sphinx==1.3.1 10 | -------------------------------------------------------------------------------- /sample_config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # This file is used to configure the environment that Vagrant sets up 3 | # when you launch a local lab environment. To make use of this, open 4 | # the file named "sample_config.yaml", save it to a new file named 5 | # "private_config.yaml", and make the necessary edits. Read the 6 | # documentation linked below for more support. 7 | # 8 | # http://python-minecraft.readthedocs.org/en/latest/other-setups/vagrant.html 9 | 10 | # Set your Minecraft player name in the field below. Failure to do 11 | # this will allow you to connect to the server, but you will not be 12 | # able to place or destroy blocks. Note, this is your player name, not 13 | # your email address. 14 | mojang_account: 'YOUR_PLAYER_NAME' 15 | 16 | # Set an IPython password in the field below. IPython will ask you for 17 | # this password when you connect. 18 | ipython_password: 'fooBARbaz' 19 | 20 | 21 | #### ADVANCED SETTINGS. You probably don't need to modify anything 22 | #### other than the settings above. 23 | 24 | # Specify the name of the Docker image to launch for the 25 | # environment. The value below always uses the latest published image 26 | # on the Docker Hub. 27 | image_name: 'coderdojotc/python-minecraft-student:latest' 28 | 29 | # Specify the name of the Git repository to clone into the 30 | # environment. If no repository is specified, the current directory is 31 | # assumed to be a repository, and it will be used instead. 32 | coderdojo_source_code: 'https://github.com/CoderDojoTC/python-minecraft.git' 33 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup, find_packages 4 | 5 | setup( 6 | name='python-minecraft', 7 | version='1.3', 8 | packages=find_packages(), 9 | 10 | description='Python programming modules for Minecraft', 11 | 12 | author='Aron Nieminen, Mojang AB; Martin O\'Hanlon', 13 | 14 | classifiers=[ 15 | 'Development Status :: 3 - Alpha', 16 | 'Intended Audience :: Developers', 17 | 'License :: Public Domain', 18 | 'Operating System :: OS Independent', 19 | 'Programming Language :: Python', 20 | ], 21 | 22 | platforms=['Any'], 23 | 24 | install_requires=[ 25 | ], 26 | 27 | entry_points={ 28 | }, 29 | ) 30 | --------------------------------------------------------------------------------